以下代码来自“Inside the C ++ object model”
#include <iostream>
using namespace std;
class X{};
class Y: public virtual X{};
class Z: public virtual X{};
class A: public Y, public Z{};
int main()
{
cout<<sizeof(X)<<" "<<sizeof(Y)<<" "<<sizeof(Z)<<" "<<sizeof(A)<<endl;
return 0;
}
在我的电脑(Windows,VS2010)中,输出为:
1 4 4 8
这是我的问题
1,sizeof(X)= 1
本书说X类型生成两个实例,比如说xa和xb。编译在A中插入一个字节,以便xa和xb可以有不同的地址。我不太明白原因。
2,sizeof(Y)= 4
通过使用虚拟继承,我们还有一个额外的虚拟指针吗?我想这可能与多态中的虚拟指针不同。任何人都可以给我Y的内存布局吗?
谢谢!
答案 0 :(得分:6)
class Y size(4):
+---
0 | {vbptr}
+---
+--- (virtual base X)
+---
Y::$vbtable@:
0 | 0
1 | 4 (Yd(Y+0)X)
vbi: class offset o.vbptr o.vbte fVtorDisp
X 4 0 4 0
答案 1 :(得分:1)
空类的sizeof总是返回1.这是一个空类的单个虚拟字节。
A保存虚拟表中的两个条目, 一个为Y. 其他为Z
所以两个指针的大小,即8.
Y和Z hold两者在其虚拟表中都有一个X条目,因此大小为4.
答案 2 :(得分:1)
一个对象将包括一个Y对象,一个Z对象(按此顺序)和只有一个 X对象(由Y和Z中的指针引用),因为Y和Z实际上都是从X,因此意味着当多重继承发挥作用时,只有一个X对象将在子类中实例化。 A仍然有两个对象(一个Y,一个Z),因此sizeof = 8(因为它们都具有sizeof = 4)。但Y和Z中指向X对象的指针都指向相同的地址。
继承树将如下所示:
X
/ \
Y Z
\ /
A
答案 3 :(得分:0)
类 - 必须至少为1个字节的原因是我们有一个X数组。如果它们是0个字节,那么&amp; array [1]将具有与&amp; array [3]相同的地址,其中没有人如果你不得不编写代码来检查它并且通常没有任何意义,那么会期望,会破坏代码,会很烦人。
Y只是
static void* virtual_ptr1 //note this is in virtual table and cannot be edited
您可以将vtable(类和虚函数的虚拟指针)视为静态变量,您无法通过手动/代码编辑(或至少不应该编辑)。将其视为编译器保留的静态变量