C++对象模型之Data语意学

对于下列程序,它们的sizeof结果:

class x{};
class y : public virtual x{};
class z : public virtual x{};
class a : public y, public z{};

在visual studio 2013编译环境下:


1、空类的sizeof是1 byte,是被编译器安插进去的一个char,这样使得class的两个object得以在内存中配置独一无二的地址;

例如: x a,b;

2、对于y和z的大小收到三个因素影响

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

当支持virtual base class时,在派生类中,这种额外负担反映在某种形式的指针上,或者指向virtual base class subobject,或者指向相关表格:表格中存放不是virtual base class subobject的地址,就是偏移位置(offset)。

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

virtual base class x subobject 的1bytes大小也出现class y和z身上,传统上它被放在派生类的固定(不变动)部分的尾端,但是某些编译器会对empty virtual base class提供特殊支持。例如visual studio2013是作了特殊优化,

(3)Alignment 的限制

alignment 就是将数值调整到某数的整数倍,在32位计算机上,通常alignment为4byte(32位),以使bus的运输量达到最高效率。

未加特殊优化的编译器对于x/y/z的对象布局:


在vs上作了特殊优化后,优化策略是:一个empty virtual base class被视为派生类对象的最开头的一部分,也就是它并没有花费任何的额外空间 ,节省了1byte,也就不需要3bytes的填补。


3、class A的大小

(1)未特殊处理empty virtual base class的编译器

  • 被大家共享的唯一一个class x实例,大小为1byte。

virtual base class subobject只会在派生类中存在一份实例,不管在class继承体系中出现多少次。

  • base class y的大小,减去因virtual base class x而配置的大小,结果是4bytes。base class z的算法亦同,加起来是8bytes。
  • class a自己的大小:0 bytes。
  • class a的alignment数量,前述三项总和,表示调整前的大小是bytes,class a必须调整至4bytes边界,所以必须填补3bytes,结果是12byte.。

(2)对empty base class作了处理的编译器

class x实例的1 byte被拿掉,于是额外3bytes填补额也不必要了。因此class a的大小将是8 bytes。

猜你喜欢

转载自blog.csdn.net/qq_32164245/article/details/80872197