C++虚继承类大小疑问:为何类C的大小为32?
解答C++虚继承类C的大小问题
首先能确定你是在64位系统下测试的——毕竟虚表指针、虚基类指针都是8字节,内存对齐规则按8字节来。
先拆解关键的类布局和大小计算:
类A的大小(16字节)
类A的组成:
char k[3]:占3字节- 虚表指针(vptr):占8字节(因为有虚函数
a()) - 填充字节:5字节(为了凑够8字节对齐,3+8=11,补5字节到16)
所以sizeof(A)=16,这个你已经理解了。
类C的大小(32字节)
你之前的计算逻辑错在对虚继承内存布局的理解偏差——虚继承的基类子对象不是直接跟在子类成员后面,而是有固定的布局规则(以GCC/Clang这类主流编译器为例):
类C的内存布局顺序是:
- 子类自身成员:
char i[3],3字节 - 子类的虚表指针:8字节(因为C自己有虚函数
c(),需要独立的虚表指针) - 虚基类指针(vbptr):8字节(虚继承专属,用来定位虚基类A在内存中的位置)
- 填充字节:到这里3+8+8=19,要凑8的倍数,补5字节到24
- 虚基类A的完整子对象:16字节(和单独的A大小一致,包含它的成员、虚表指针和填充)
把这些加起来:24 + 16 = 32,正好和你得到的输出匹配。
你之前错误地把A的子对象放在最前面计算,忽略了虚继承布局中“虚基类子对象放在对象末尾”的规则,而且每一段都要单独满足内存对齐,不是把所有元素简单相加后补一次填充。
额外补充:类D的大小(48字节)
顺便说下类D的大小为什么是48:
D同时继承B(普通继承A)和C(虚继承A),虚继承会保证整个D对象里只有一份A的子对象。它的布局大概是:
- B的部分:16字节(包含A的子对象)
- C的部分(去掉重复的A子对象):24字节(i[3]+vptr+vbptr+填充)
- D自身成员
h[3]:3字节 - 填充字节:补5字节凑8的倍数
总和:16+24+3+5=48,和输出一致。
内容的提问来源于stack exchange,提问作者ddungisthebest
相关产品推荐
相关产品推荐

