【C++】多态 ⑧ ( 验证指向 虚函数表 的 vptr 指针 | 对比定义了虚函数的类和没有定义虚函数类的大小 )

文章目录

  • 一、验证指向 虚函数表 的 vptr 指针 是否存在
    • 1、虚函数表与 vptr 指针由来
    • 2、虚函数类与普通函数类对比 - 多出了 vptr 指针的大小


对比 定义了 虚函数 的类 与 没有定义虚函数的类 的大小 , 其它成员都相同 , 定义了虚函数的类多出了 4 字节 , 多出的 4 字节就是 vptr 指针占用的内存空间 ;





一、验证指向 虚函数表 的 vptr 指针 是否存在




1、虚函数表与 vptr 指针由来


" 虚函数表 " 由 C++ 编译器 负责 创建 与 维护 , 被 virtual 关键字 修饰的 虚函数 , 会自动 被 C++ 编译器 存储到 " 虚函数表 " 中 ;


虚函数表 创建 : 在 类 中使用 virtual 关键字 声明 虚函数 时 , C++ 编译器 会自动为该类生成 " 虚函数表 " ;

  • 生成虚函数表的前提是 至少有 1 个虚函数 ;
  • 如果 没有虚函数 , 就不会生成虚函数表 ;
  • 如果 类 中有 virtual 虚函数 , 则 该类的 每个对象 中 , 都有一个 指向 虚函数表的 vptr 指针 ;

虚函数表 存储 虚函数指针 : " 虚函数表 " 是 存储 " 类成员函数指针 " 的 数据结构 , 是一个 函数指针数组 , 数组中的元素都是函数指针 , 具体存储的都是 指向 类中的虚函数 的指针 ;

  • 如果 子类 中 , 重写了 父类的 virtual 虚函数 , 那么 C++ 编译器会在 子类 虚函数表 中放入该 子类虚函数的 函数指针 ;

如果 C++ 类中存在 virtual 虚函数 , 在创建对象时 , 会生成 虚函数表 Virtual Function Table , 简称 vtable ;

C++ 编译器 编译 代码时 , 会自动为该类 添加 一个 vptr 指针 成员变量 , 该指针 会指向 虚函数表 ;


2、虚函数类与普通函数类对比 - 多出了 vptr 指针的大小


下面的代码中 , 定义了 2 个类 , 区别是 一个定义了 virtual 虚函数 , 另外一个没有定义 虚函数 ;

  • 在 Parent 中定义了 虚函数 virtual void fun(int a) ;
  • 在 Parent2 中定义的是 普通函数 void fun(int a) ;

使用 sizeof 函数 , 获取这两个类的大小 , 判断两个类的区别 ;

最终得到 , 有 虚函数 的 类 , 比 没有 虚函数 的 类 , 多 4 字节 , 也就是一个指针的大小 ,

定义了 虚函数 的类 , 多出的 4 字节就是 vptr 指针的大小 ;


代码示例 :

#include "iostream"
using namespace std;

// 父类
class Parent {
public:
	virtual void fun(int a)
	{
		cout << "执行 父类 Parent 的 virtual void fun(int a) 函数" << endl;
	}
	int a;
};

// 父类
class Parent2 {
public:
	void fun(int a)
	{
		cout << "执行 父类 Parent2 的 void fun(int a) 函数" << endl;
	}
	int a;
};

// 子类
class Child : public Parent {
public:
	virtual void fun(int a)
	{
		cout << "执行 子类 virtual void fun(int a) 函数" << endl;
	}
};

int main() {

	Parent* p;
	// 创建 Child 子类对象时
	// 发现有 virtual 虚函数 会创建 虚函数表
	// 在对象中使用 vptr 指针指向 虚函数表 首地址
	Child c;

	// 将父类指针指向子类对象
	p = &c;
	// 通过父类指针调用子类对象的 fun 函数
	p->fun(1);

	// 打印 Parent 的 大小
	cout << "sizeof(Parent) : " << sizeof(Parent) << endl;

	// 打印 Parent2 的 大小
	cout << "sizeof(Parent2) : " << sizeof(Parent2) << endl;

	// 控制台暂停 , 按任意键继续向后执行
	system("pause");

	return 0;
}

执行结果 :

执行 子类 virtual void fun(int a) 函数
sizeof(Parent) : 8
sizeof(Parent2) : 4
Press any key to continue . . .

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/111201.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Windows11无法打开Photoshop CC 2017问题解决

情况描述&#xff1a; Windows11上&#xff0c;双击Photoshop CC 2017没反应 解决办法&#xff1a; 此时需要启动Windows的“事件查看器”来确认问题出在哪里。可以直接通过开始菜单搜索启动&#xff0c;也可以通过右键点击“此电脑”->“管理”&#xff0c;然后找到事件查…

《微聊》JMeter性能测试报告

文章目录 准备工作JMeter准备工作本地配置代理 测试规划测试方向预期方向异常处理 压力测试录制注册功能压力注册功能压力脚本录制录制功能压力测试脚本完善注册功能压力测试结果 登录功能压力录制登录功能压力测试脚本构造压力测试数据完善登录功能性能测试脚本登录功能压力测…

Servlet的继承树,生命周期和线程不安全

1、Servlet 继承树 3)Servlet的继承树 - Servlet接口public interface Servlet{public void init(config);public void service(request,response);public void destroy();} - GenericServlet抽象类public abstract class GenericServlet implements Servlet{实现了init方法和d…

android查漏补缺(8)Binder framework架构和调用方法

1.Binder简介 Binder是android系统中实现进程间通信的主要组件&#xff0c;包括各种AMS,PMS,SMS等服务和APK的通信都是通过binder实现。但是调用过PMS的同学肯定会有疑问&#xff0c;既然是进程通信&#xff0c;怎么没有消息的发送和接收&#xff0c;为什么调用不同进程的服务的…

出海数字化,国产CRM如何支撑?纷享销客这样思考

2023年&#xff0c;疫情阴霾逐渐消散&#xff0c;企业全球化扩张的齿轮重新加速。以科技企业、高端制造业为代表的优秀企业引领中国企业出海浪潮&#xff0c;外资企业在华的经营活跃度也在提升。 无论是”外资在华经营“还是”中资出海“&#xff0c;这些具备全球化理想的企业…

宝塔安装mongodb插件失败的解决办法

安装时始终不成功。 进入控制台进行安装 /www/server/php/71# pecl install mongodb WARNING: channel "pecl.php.net" has updated its protocols, use "pecl channel-update pecl.php.net" to update pecl/mongodb requires PHP (version > 7.2.0, …

Dataworks API:调取 MC 项目下所有表单

文章目录 前言Dataworks API 文档解读GetMetaDBTableList 接口文档 API 调试在线调试本地调试运行环境账密问题请求数据进一步处理 小结 前言 最近&#xff0c;我需要对公司的数据资产进行梳理&#xff0c;这其中便包括了Dataworks各个项目下的表单。这些表单&#xff0c;作为…

Android 处理多个TextView, 文案过长时前面文本省略的问题

遇到显示多个TextView&#xff0c;文案过短时&#xff0c;这几个TextView跟随显示&#xff0c;文案过程时&#xff0c;前面TextView省略&#xff0c;后个的TextView全显示。效果如下&#xff1a; 用ConstraintLayout 没有得到解决&#xff0c;采用 RelativeLayout 解决 代码如…

按相同时间切割长视频

需求 将一段1小时的.mkv视频&#xff0c;按每5分钟切割&#xff0c;并转成.mp4 工具 格式工程 x64 5.15&#xff0c;下载 这真是个好工具&#xff0c;考虑过PR&#xff0c;无意间发现这软件很强大 实现步骤 第一步&#xff1a;选择视频&#xff0c;导出MP4&#xff0c;添…

libcurl库的网页爬虫程序

示例代码&#xff1a; #include <curl/curl.h> #include <iostream> ​ int main() {CURL *curl;CURLcode res; ​curl_global_init(CURL_GLOBAL_DEFAULT); ​curl curl_easy_init();if(curl) {curl_easy_setopt(curl, CURLOPT_URL, "/");curl_easy_se…

CSS与基本选择器

<div class"c1" id"d1"></div> CSS基本知识 什么是css&#xff1a;CSS&#xff08;Cascading Style Sheet&#xff0c;层叠样式表)定义如何显示HTML元素。 当浏览器读到一个样式表&#xff0c;他就会按照这个样式l来进行渲染。其实就是让HT…

雷迪管线探测仪故障定位仪维修RD8100

英国雷迪管线探测仪常见维修型号&#xff1a;RD4000&#xff1b;RD7000&#xff1b;RD8000&#xff1b;RD8100等。 应该范围&#xff1a;是目前探测煤气、电力、自来水、排水等各类地下管线的仪器之一。 雷迪管线探测仪具有直连线特点&#xff1a;用直连线可以将发射机直接与需…

基于Canal同步MySQL数据到Elasticsearch

基于Canal同步MySQL数据到Elasticsearch 基于 canal 同步 mysql 的数据到 elasticsearch 中。 1、canal-server 相关软件的安装请参考&#xff1a;《Canal实现数据同步》 1.1 pom依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmln…

Android图形系统之HWComposer、ComposerHal、ComposerImpl、Composer、Hwc2::Composer实例总结(十四)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药. 更多原创,欢迎关注:Android…

利用远程IO模块,轻松驾驭食品包装生产的自动化

常见的自动化包装系统&#xff0c;它的核心部分通常由一系列高端设备组成&#xff0c;包括自动开箱机、自动封箱机、自动捆扎机、装箱机器人、码垛机器人等。这些设备协同工作&#xff0c;形成一条高效运转的生产线&#xff0c;从开箱到装箱&#xff0c;再到码垛&#xff0c;每…

多测师肖sir_高级金牌讲师_性能测试之badboy录制脚本02

性能测试之badboy录制脚本 一、下载安装包&#xff0c;点击安装 二、点击我同意 三、选择路径&#xff0c;点击install 打开以下界面&#xff0c;表示安装成功 第二步&#xff1a;录制流程 界面视图&#xff0c;模拟浏览器&#xff0c;能够进行操作 需要录制脚本的URL 点…

MLF - 麻辣粉

MLF全称中期借贷便利&#xff08;Medium-term lending Facility&#xff09;,理解为央行向商业银行、政策银行发放的贷款&#xff0c;但需要符合一定要求才可向央行申请。银行通过MLF向央行借款的时候&#xff0c;需要提供担保品。一般为国债、央行票据、政策性金融债、地方债、…

C++设计模式_19_Memento 备忘录(理解,目前多使用序列化方案来实现)

Memento 备忘录模式也属于“状态变化”模式&#xff0c;它是一个小模式&#xff0c;在今天来看有些过时&#xff0c;当今已经很少使用当前模式实现需求&#xff0c;思想却不变&#xff08;信息隐藏&#xff09;&#xff0c;目前多使用序列化方案来实现。本系列所介绍的模式&…

企业金蝶KIS软件服务器中了locked勒索病毒怎么办,勒索病毒解密

最近一段时间&#xff0c;网络上的locked勒索病毒又开始了新一波的攻击&#xff0c;给企业的正常生产生活带来了严重影响。经过最近一段时间云天数据恢复中心对locked勒索病毒的解密&#xff0c;为大家整理了以下有关locked勒索病毒的相关信息。近期locked勒索病毒主要攻击金蝶…

【httpd】 Apache http服务器目录显示不全解决

文章目录 1. 文件名过长问题1.1 在centos中文件所谓位置etc/httpd/conf.d/httpd-autoindex.conf1.2 在配置文件httpd-autoindex.conf中的修改&#xff1a;1.3 修改完成后重启Apache&#xff1a; 1. 文件名过长问题 1.1 在centos中文件所谓位置etc/httpd/conf.d/httpd-autoindex…