C++虚继承之类的实际大小
作者:网络转载 发布时间:[ 2012/10/17 10:50:26 ] 推荐标签:
这几天翻箱底将去年买的《深度探索C++对象模型》这本NB的书拿出来看看,The Semantics of Data这一章中发现了一个过去一直没有想到的一个问题,问题如下
输出下面class的大小:
class X{};
class Y : public virtual X{};
class Z : public virtual X{};
class A : public Y, public Z{};
继承关系如下图:
这是可能大家会觉得他们的大小都应该是0,因为他们中没有任何一个有明显的数据,只表示了继承关系。但是至少也认为class x应该是0吧,他什么都没有。结果却让你想不到,我在vs2010环境下测试的大小是:(不同编译器可能这个大小是不一样)
cout<<"sizeof X: " <<sizeof X<<endl
<<"sizeof Y: " <<sizeof Y<<endl
<<"sizeof Z: " <<sizeof Z<<endl
<<"sizeof A: " <<sizeof A<<endl;
很奇怪吧,为什么是这个结果呢。一个空的class事实上并不是空,它有一个隐藏的1 byte,这个是编译器安插进去的char,这样可以保证定义的对象在内存中的大小是的,这个地方你可以自己测试下,比如:
X xa,xb;
if (&xa == &xb)
cout<<"is equal"<<endl;
else
cout<<"not equal"<<endl;
但是让人搞不懂的是Y、Z的大小。主要大小受三个因素的影响:
● 语言本身所造成的额外负担,当语言支持虚基类的时候,导致一个额外的负担,这个一般都是一个虚表指针。里面存储的是虚基类子对象的地址,是偏移量。
● 编译器对于特殊情况所提供的优化处理,因为class X有1 byte的大小,这样出现在了class Y和class Z身上。这个主要视编译器而定,比如某些存在这个1byte但是有些编译器将他忽略了(因为已经用虚指针了所以这个1byte可以不用作为内存中的一个定位)。
● Alignment的限制,是所谓的对齐操作,比如你现在占用5bytes编译器为了更有效率地在内存中存取将其对齐为8byte。
下面说明在vs2010中的模型,因为有了虚指针后所以1byte不用了,所以class Y和class Z的大小是4bytes,如下图:
现在你觉得class A的大小应该是多少呢?一个虚基类子对象只会在派生类中存在一份实体,不管他在继承体系中出现多少次,所以公用一个1byte的classX实体,再加上 class Y和class Z这样有9bytes,如果有对齐的话是12bytes但是vs2010中省略了那1byte所以不存在对齐直接是8bytes。谜底终于揭开了!
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11