菱形继承结构中子类D的sizeof结果异常问题咨询
为什么多重继承后
sizeof(D)是8而不是4? 这个问题的核心在于非虚多重继承中的基类子对象重复,以及C++编译器的内存对齐规则和空基类优化(EBO)的作用。咱们一步步拆解:
1. 先看各个类的大小逻辑
class A {}:空类的大小是1字节,这是C++标准规定的——为了保证同一个类的不同对象拥有唯一的内存地址,编译器会给空类分配1字节的占位空间。class B : public A { int data; }:这里触发了空基类优化(EBO)——当一个空基类被继承,且派生类有非静态成员时,编译器会把空基类的占位空间合并到派生类的内存布局中,不需要额外占用空间。所以sizeof(B)等于sizeof(int)也就是4字节,符合你的测试结果。class C : public A {}:C没有任何非静态成员,无法触发EBO,所以它的大小还是1字节(来自A的占位空间)。
2. D的内存布局为什么是8字节?
D同时继承了B和C,而且都是非虚继承。这意味着:
D的内存中会包含一个完整的B子对象(4字节),以及一个完整的C子对象(1字节)。- 这两个子对象(
B和C)必须拥有独立的内存地址,不能重叠——因为C里面的A子对象和B里面的A子对象是完全独立的两个实体(非虚继承下不会共享基类子对象)。
接下来是内存对齐的影响:
C++编译器会保证对象的内存对齐到其成员中最大的对齐单位。这里B里的int是4字节对齐,所以整个D对象也需要对齐到4字节的倍数。C的1字节后面会被填充3字节的空空间,来满足对齐要求。
所以最终D的大小是:B的4字节 + (C的1字节 + 3字节填充) = 8字节。
额外验证:如果用虚继承会怎样?
如果把B和C都改成虚继承A:
class A {}; class B : virtual public A { int data; }; class C : virtual public A {}; class D : public B, public C {};
这时候D里只会有一个共享的A子对象,不过因为虚继承会引入虚基表指针(通常占8字节,64位系统),所以sizeof(D)会变成4(int) + 8(B的虚表指针) + 8(C的虚表指针) + 1(A的占位),对齐后是24字节左右,反而更大——这也侧面说明非虚继承下的基类子对象是独立的。
内容的提问来源于stack exchange,提问作者ownfos
相关产品推荐
相关产品推荐

