虚拟继承中的类的sizeof

dea*_*mer 4 c++ virtual-inheritance

使用虚拟继承时类的大小如下

ABase=4(sizeof imem)
BBase=12(sizeof imem+ABase+VBase_ptr)
CBase=12(sizeof imem+ABase+VBase_ptr) 
Run Code Online (Sandbox Code Playgroud)

这是有道理的,但我不明白为什么大小ABCDerived是24.

class ABase{ 
        int iMem; 
}; 

class BBase : public virtual ABase { 
        int iMem; 
}; 

class CBase : public virtual ABase { 
        int iMem; 
}; 

class ABCDerived : public BBase, public CBase { 
        int iMem; 
}; 
Run Code Online (Sandbox Code Playgroud)

Joh*_*ing 5

这将是非常依赖平台的,但我认为我们可以理解正在发生的事情.

首先,标准没有规定如何实施虚拟无意.就标准而言,甚至没有vtable这样的东西.

ABCDerivedBBaseCBase每个由一个int.还有一个实例ABase包含一个int.最后有一个vtable ptr.

a的大小int取决于平台 - 它不是4个字节.但是如果我们假设它是4个字节,并且vtable的大小也是4个字节,我们有:

int  [ABCDerived] = 4 bytes
int  [CBase]      = 4 bytes
int  [BBase]      = 4 bytes
int  [ABase]      = 4 bytes
vtable            = 4 bytes
                 -------------
                   20 bytes
Run Code Online (Sandbox Code Playgroud)

但这并不意味着sizeof (ABCDerived)20岁.对齐也在这里发挥作用.标准允许编译器增加对象的大小,以便大小可以被整个单词整除.

考虑:

class ABase{ 
            int iMem; 
}; 

class BBase : public virtual ABase { 
            int iMem; 
}; 

class CBase : public virtual ABase { 
            int iMem; 
}; 

class ABCDerived : public BBase, public CBase { 
            int iMem; 
}; 

int main()
{
    ABCDerived d;
    BBase& b = d;
    ABase* ab = &b; 
    CBase& c = d;
    ABase* ac = &b; 

    cout << hex << (void*) ab << "\n"
        << hex << (void*) ac << "\n";

    cout << sizeof (d) << "\n" << sizeof (int) << "\n";
}
Run Code Online (Sandbox Code Playgroud)

输出28在我的64位Linux机器上.

但是,如果我打开打包(使用依赖于平台的#pragma开关):

#pragma pack (1)
Run Code Online (Sandbox Code Playgroud)

输出现在是20.

所以,所有这些的长短都是:

这里有很多与平台相关的东西.您不能说对象的大小是这个或那个,至少不使用更多依赖于平台的东西并且知道您的编译器如何实际实现虚拟继承.它的大小是它的大小.