对于下列程序,它们的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。