您的位置:首页 > 编程语言 > C语言/C++

深度探索C++对象模型-Data语意学01

2016-12-09 11:05 471 查看
菱形继承实例

Ex:

class X{};
class Y :public virtual X{};
class Z :public virtual X{};
class A :public Y, public Z{};

继承关系如图:



sizeof X 的结果为1

sizeof Y 的结果为8

sizeof Z 的结果为8

sizeof A 的结果为12

注意:在VS2013下我的运行结果是1、4、4、8,原因是因为VS2013编译器对empty virtual base class提供了特殊支持,做了优化。原因稍后解释。

1、X的大小

X并不是空的,它有一个隐藏的1byte大小,那是被编译器安插进去的一个char。这使得这一class的不同实例化对象在内存中配置独一无二的地址。

Ex:X x1; X x2;x1和x2的地址不相同

2、Y和Z的大小

Y和Z的大小受到三个因素的影响:

(1)语言本身所造成的额外负担(overhead)

主要是虚拟继承,虚函数指针(vptr),虚函数表格(vtbl)造成的额外负担

(2)编译器对于特殊情况所提供的优化处理

某些编译器会对empty virtual base class提供特殊支持

(3)Alignment的限制

alignment就是将数值调整到某数的整数倍。在32位计算机上,通常alignment为4bytes(32位)

class Y和Z的大小目前为5 bytes。因为要对齐,所以最后的结果是8 bytes。

以下是Y和Z的对象布局



在一些新近的编译器中,一个empty virtual base class被视为derived class object最开头的一部分,也就是说它并没有花费任何的额外空间。因为既然有了members,就不需要原本为了empty class而安插的一个char。所以在此模型下,Y和Z的大小都是4。

以下是这种编译器的对象布局:



3、A的大小

一个virtual base class subobject只会在derived class中存在一份实例,不管它在class继承体系中出现了多少次!

class A的大小由以下几点决定:

(1)被大家共享的唯一一个class X实例,大小为1 byte

(2)Base class Y的大小,减去因virtual base class X而配置的大小,结果是4 bytes。

Base class Z的算法亦相同。加起来是8 bytes。

(3)class A自己的大小:0 byte

(4)class的alignment数量(如果有的话)。前述三项总和,表示调整前的大小是9 bytes。class A必须调整至4 bytes边界,所以需要填补3 bytes。结果是12 bytes。

如果是优化了empty virtual base class的编译器,class X实例的那1 byte将被拿掉,于是class A的大小为8 bytes。

注意:如果virtual base class X中放置一个(以上)的data members,两种编译器就会产生出完全相同的对象布局

static data members,则放置在程序的一个全局数据段,不会影响个别的class object的大小。在程序之中,不管该class被产生出多少个objects,static data members永远只存在一份实例。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息