虚拟继承中的类的sizeof

时间:2013-08-02 15:46:06

标签: c++ virtual-inheritance

使用虚拟继承时类的大小。

ABase=4(sizeof imem)
BBase=12(sizeof imem+ABase+VBase_ptr)
CBase=12(sizeof imem+ABase+VBase_ptr) 

这是合理的,但我不明白为什么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; 
}; 

2 个答案:

答案 0 :(得分:5)

这将取决于平台,但我认为我们可以理解正在发生的事情。

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

ABCDerivedBBaseCBase每个都由int组成。还有一个ABase实例,由int组成。最后有一个vtable ptr。

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

但这并不意味着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";
}

我的64位Linux机器上的输出为28

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

#pragma pack (1)

输出现在是20。

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

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

答案 1 :(得分:0)

大小应为20 ,正如您使用的虚拟继承ABCDerived将不会继承ABase IMem两次。正如你所说它给出了24,可能是你的编译器不支持虚拟继承。