`
explorers
  • 浏览: 14443 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
最近访客 更多访客>>
社区版块
存档分类
最新评论

http://blog.csdn.net/openhero/archive/2006/04/08/655002.aspx

阅读更多
出自http://blog.csdn.net/openhero/archive/2006/04/08/655002.aspx
C++ 内存布局(二) 虚继承 ---Empty virtual base classs (空虚基类) 收藏

上一次只是给出一个代码http://blog.csdn.net/OpenHero/archive/2006/04/02/648005.aspx, 和运行过程中的内存位置,现在具体的按照步骤分析一下C++中虚拟继承中的情况,

由于C++ stand(C++ 标准委员会) 并没有规定具体实现的办法,各个编译器厂商可能都采用不同的实现方法,

或许在不同的年代使用的方法也不相同,有可能就会得到不同的结果,这里,我采用VC7.1作为调试工具,由潜

入深的一步步分析C++ 虚继承中的内存布局;

这一部分由Empty virtual base calss (空虚基类:空的calss)入手,查看VC7.1中是如何实现虚拟继承的.

下面给出测试的代码:

一,菱形的继承模式

class A
{ };

class B : virtual public A
{
};

class C : virtual public A
{
};

class D : public C, public B
{
};


int _tmain(int argc, _TCHAR* argv[])
{
A a;
B b;
C c;
D d;

int *pd   = (int*)&d;
int *pd_c = (int*)(C*)(&d);
int *pd_b = (int*)(B*)(&d);
int *pd_a = (int*)(A*)(&d);

cout<< sizeof(a) << endl;
cout<< sizeof(b) << endl;
cout<< sizeof(c) << endl;
cout<< sizeof(d) << endl;
cout<< pd   << endl;
cout<< pd_c << endl;
cout<< pd_b << endl;
cout<< pd_a << endl;

return 0;
}

有人会问,

class A
{ };

A a, 其中的a会有大小嘛?当然,a里面什么都没有,姑且就认为它是空的吧,但是,编译器如何才能记住a,而又

是空?你能想到一种实现的方法嘛?所以,编译器为了记住空的a,在a的内部放入了一个char的标记,作为它的

唯一标识,这样编译器才能认识那个a.  如果你有兴趣,你可以尝试定义A a,b; 然后你看看a和b是否是一

样的?现阶段来说,应该是不一样的,或许以后谁会发明新的实现方式,那个时候或许是一样也有可能了。

现在让我们看看上面程序的输出情况,如下:
1
4
4
8
0012FEAC
0012FEAC
0012FEB0
0012FEB4

这里我先不对上面的输出做出解释,或许你看了这样的输出会有疑惑,是不是和你想象的不一样?带着疑问

继续往下面看。
下面我再给出两段代码,同时给出他们各自的输出,然后再对这些输出做出解释:

二,六边形(菱形一)
class A
{ };

class B : virtual public A
{
};

class C : virtual public A
{
};

class D : /*virtual */public B
{
};

class E : /*virtual */public C
{

};
class F : public E, public D
{
};
int _tmain(int argc, _TCHAR* argv[])
{
A a;
B b;
C c;
D d;
E e;
F f;

int *pf   = (int*)&f;
int *pf_e = (int*)(E*)(&f);
int *pf_d = (int*)(D*)(&f);
int *pf_c = (int*)(C*)(&f);
int *pf_b = (int*)(B*)(&f);
int *pf_a = (int*)(A*)(&f);

cout<< sizeof(a) << endl;
cout<< sizeof(b) << endl;
cout<< sizeof(c) << endl;
cout<< sizeof(d) << endl;
cout<< sizeof(f) << endl;
cout<< pf   << endl;
cout<< pf_e << endl;
cout<< pf_d << endl;
cout<< pf_c << endl;
cout<< pf_b << endl;
cout<< pf_a << endl;

return 0;
}
输出结果:
1
4
4
4
4
8
0012FE94
0012FE94
0012FE98
0012FE94
0012FE98
0012FE9C

三,六边形(菱形二)

class A
{ };

class B : virtual public A
{
};

class C : virtual public A
{
};

class D : virtual public B
{
};

class E : virtual public C
{

};
class F : public E, public D
{
};
int _tmain(int argc, _TCHAR* argv[])
{
A a;
B b;
C c;
D d;
E e;
F f;

int *pf   = (int*)&f;
int *pf_e = (int*)(E*)(&f);
int *pf_d = (int*)(D*)(&f);
int *pf_c = (int*)(C*)(&f);
int *pf_b = (int*)(B*)(&f);
int *pf_a = (int*)(A*)(&f);

cout<< sizeof(a) << endl;
cout<< sizeof(b) << endl;
cout<< sizeof(c) << endl;
cout<< sizeof(d) << endl;
cout<< sizeof(e) << endl;
cout<< sizeof(f) << endl;
cout<< pf   << endl;
cout<< pf_e << endl;
cout<< pf_d << endl;
cout<< pf_c << endl;
cout<< pf_b << endl;
cout<< pf_a << endl;

return 0;
}
输出结果:
1
4
4
8
8
16
0012FE84
0012FE84
0012FE88
0012FE8C
0012FE90
0012FE8C

下面对其中的一,二做分析,三是一个有趣的现象,你可以考虑考虑:)

可以看到,只要有virtual的地方,都多出4个字节,用来干嘛?
在VC的编译器中,采用了virtual base calss pointer的方式来实现虚继承,从而保证子类回溯到基类的时

候只存在一个实体。多出来的4个字节就是用来存放各自的指向virtual base class 的地址的。

你可能又要问,a的大小为1,b,c……的大小只是4个4个增加,考虑内存对其,那不是会更大吗?

看到前面提到的一个问题了吗?
编译器只是为了记住a的时候才把a标示出来,如果知道a是空的,它既然有了子类,子类表示出来的时候,

当然基类就存在其中了:)

你可能又问? 那为什么不把子类也表示为1,不就行了吗?当然不行,就像上面提到的,因为是为了实现虚

继承的菱形一样的继承样式,在子类中只存在基类一个实体,所以,就才用了指针的方式,而不是把整个实

体放到子类的内存中。

在以后的内容中,会不断添加参数,函数,虚函数,分析虚继承中内存的分布。


声明:如果有网站转载,请把出处和连接加入到网页上,谢谢,咱,熬夜很困阿~~~
ps:太困,眼睛都睁不开了~~~~不行了,要睡觉了~~~~ 难免有打错的地方,请原谅
分享到:
评论

相关推荐

    CUDA学习入门资料整理

    资料内容整理至openhero(赵开勇)的blog,非常好的CUDA入门资料。(thanks to openhero),所有贡献和辛苦属于赵开勇

    CUDA_easy_start_up

    高清晰地openhero的CUDA_easy_start_up,不必在为cuda的环境设置而烦恼了!

    Suno AI Download 免费下载Suno AI 音乐

    网站描述:Sunoaidownload——从分享链接中轻松下载Suno AI生成的歌曲文件 内容概要: 这是一个专门提供Suno AI生成的歌曲文件下载服务的网站,用户可以通过分享链接轻松获取所需文件。本网站提供高质量、多样化的音乐资源,满足不同用户的需求。 适用人群: 该网站适用于所有热爱音乐、需要音乐素材的用户,特别适合音乐创作者、音乐爱好者、学生、教师等人群使用。 使用场景: 该网站的使用场景非常广泛,具体包括以下几个方面: 1. 音乐创作:音乐创作者可以使用本网站提供的歌曲文件进行创作,丰富作品内容,提升作品质量。 2. 音乐学习:学生和教师可以使用本网站的歌曲文件进行音乐学习,提高音乐素养和技能。 3. 娱乐休闲:普通用户可以使用本网站的歌曲文件进行放松、娱乐和休闲,享受音乐带来的愉悦。 其他说明: 本网站提供高速、稳定的下载服务,确保用户能够快速获取所需文件。同时,我们注重版权保护,只提供合法授权的歌曲文件,避免侵犯他人权益。为了更好地服务用户,我们不断优化网站功能和用户体验,欢迎提出宝贵意见和建议。此外,为了保障用户数据安全,我们采取了先进的安全措施。

    基于Python的Django配置Celery设计源码

    本项目是基于Python的Django配置Celery设计源码,包含20个文件,其中主要包含17个py源代码文件。系统采用了Python编程语言,实现了Django配置Celery的功能。项目结构清晰,代码可读性强,易于理解和维护。

    物联网嵌入式ESP32开发例程05-FreeRTOS操作系统之时间片调度C程序代码.rar

    1、嵌入式物联网ESP32项目实战开发。例程经过精心编写,简单好用。 2、代码使用Visual Studio Code + ESP-IDF开发,C语言编程。例程在ESP32-S3上运行。若在其他型号上运行,请自行调整。 3、如果接入其他传感器,请查看发布的其他资料。 4、ESP32与模块的接线,在代码当中均有定义,请自行对照。 5、若硬件差异,请根据自身情况适当调整代码,程序仅供参考。 6、代码有注释说明,请耐心阅读。 7、技术v:349014857;

    华为IPMS流程优化策略glz.pptx

    华为IPMS流程优化策略glz.pptx

    文字转合成语音软件工具

    文字转语音软件,两款,都非常好用,亲测有效,免费声音足够使用,需要的兄弟自行下载

    工作汇报 年终总结5.pptx

    引言 年度工作回顾 系统进展与亮点 技术创新与应用 市场反馈与用户评价 存在问题与挑战 未来展望与计划 结束语与感谢 一、引言 简要介绍智能家居系统的重要性和发展趋势 回顾本年度的工作目标和重点 二、年度工作回顾 系统建设与维护 完成的项目与里程碑 系统稳定性与可靠性提升 团队建设与培训 团队成员构成与职责 培训与技能提升活动 合作伙伴与资源整合 与供应商、合作伙伴的合作情况 资源整合与利用 三、系统进展与亮点 功能扩展与优化 新增功能介绍与效果评估 现有功能的优化与改进 用户体验提升 界面设计与交互优化 用户反馈与改进措施 四、技术创新与应用 物联网技术的应用 传感器与通信技术的升级 大数据分析与应用 智能家居的智能化管理 自动化控制与节能策略 安全防护与预警系统 五、市场反馈与用户评价 市场反馈分析 市场需求与竞争态势 市场占有率与增长趋势 用户评价总结 用户满意度调查结果

    基于SpringBoot和OpenAI的聊天机器人设计源码

    本项目是基于SpringBoot和OpenAI的聊天机器人设计源码,包含1559个文件,其中主要包含605个java源代码文件,361个js脚本文件,238个vue前端文件等。系统采用了Java、JavaScript、Vue、CSS、HTML、Shell和TypeScript技术,实现了一个基于SpringCloud的Chatgpt机器人。该项目已对接GPT-3.5、GPT-4.0、百度文心一言、stable diffusion AI绘图、Midjourney绘图等AI技术。用户可以在界面上与聊天机器人进行对话,聊天机器人会根据用户的输入自动生成回复。项目结构清晰,代码可读性强,易于理解和维护。

    2024年全球控制膨胀合金箔行业总体规模、主要企业国内外市场占有率及排名.docx

    2024年全球控制膨胀合金箔行业总体规模、主要企业国内外市场占有率及排名

    电子通信设计资料多点温度检测系统设计论文资料

    电子通信设计资料多点温度检测系统设计论文资料提取方式是百度网盘分享地址

    基于Bootstrap的树形表格设计源码

    本项目是基于Bootstrap的树形表格设计源码,包含31个文件,其中主要包含7个js脚本文件,5个css样式文件等。系统采用了JavaScript、CSS和HTML技术,实现了基于Bootstrap的树形表格功能。该项目最初出现在guns项目中,基于jquery.treegrid.js实现树形结构,但由于性能问题,重新实现了相关功能。其用法与bootstrap-table类似。项目结构清晰,代码可读性强,易于理解和维护。

    基于STM32F4的智能门锁超详细解析(矩阵键盘、OLED、舵机、HC-05蓝牙、F407ZG最小系统)可用于毕业设计.zip

    基于STM32F4的智能门锁超详细解析(矩阵键盘、OLED、舵机、HC-05蓝牙、F407ZG最小系统)可用于毕业设计.zip

    万能文件查看器 支持各种文件格式.zip

    万能文件查看器 支持各种文件格式.zip

    电子通信设计资料智能健康监护仪的研究毕业设计论文资料

    电子通信设计资料智能健康监护仪的研究毕业设计论文资料提取方式是百度网盘分享地址

    2023年中老年奶粉行业展望.pptx

    行业研究

    YOLOv8训练飞机检测模型+权重+数据集

    1、YOLOv8训练飞机检测模型,并包含标注好的飞机检测数据集,标签格式为xml和txt两种,类别名为aeroplane, 2、数据集和检测结果参考:https://blog.csdn.net/zhiqingAI/article/details/124230743 5、采用pytrch框架,代码是python的

    asp.net基于三层模式实验室仪器设备管理系统源码.7z

    实验室设备仪器管理系统基于MVC思想和三层设计模式构建,前台采用bootstrap响应式框架,后台运用div+css技术,确保用户界面的友好与兼容性。在Visual Studio 2010或更高版本软件上进行程序开发,利用sqlserver2005或更先进的数据库系统提供稳定的数据支持。 该系统包含四个核心模块:实验室登陆模块、学生模块、教师模块和管理员模块。登陆模块提供用户注册和登陆功能,确保用户信息的准确与安全。学生模块提供实验课仪器设备的信息查询、借领仪器耗材、设备事故的登记等服务,满足学生在实验过程中的各种需求。 管理员模块功能丰富,包括实验室设备信息查询、设备事故记录、设备资料管理、设备损坏管理以及设备耗材借领等。管理员可以方便地查询和统计设备仪器信息,上报和处理设备事故,更新设备操作指南,管理设备损坏信息,以及处理设备耗材的借领和归还。 实验设备管理数据库是系统的核心部分,管理员可以添加、删除、更改设备信息,记录报废、维修、申请购买以及新增设备的详细信息。所有相关信息如报废表、维修表、设备购买申请表、新增设备属性表等都会在终端实时显示,确保信息的及时性和准确性。 此

    1急急急i几i积极急急急急急急急急急急急急急急急急急急急急急急急急积极

    1急急急i几i积极急急急急急急急急急急急急急急急急急急急急急急急急积极

    TIMIT数据集下载TIMIT数据集下载,种子资源。.zip

    TIMIT数据集下载TIMIT数据集下载,种子资源。

Global site tag (gtag.js) - Google Analytics