class CBase
{
int nBase{ 0 };
};
class CA : public CBase { int nA; };
class CB : public CBase { int nB; };
class CD : public CA, public CB{ int nD; };
int main()
{
cout << "size of CBase " << sizeof(CBase) << endl;
cout << "size of CA " << sizeof(CA) << endl;
cout << "size of CB " << sizeof(CB) << endl;
cout << "size of CD " << sizeof(CD) << endl;
return 0;
}
先看普通继承下的对象大小,如上代码,结果:
size of CBase 4
size of CA 8
size of CB 8
size of CD 20
c++成员函数存储在代码段中,上面代码中sizeof(classXX)只体现了成员变量的大小,可推断,CD在继承了CA、CB后,有两份CBase。
采用虚继承可以避免上述问题吗?
class CBase
{
int nBase{ 0 };
};
class CA : virtual public CBase { int nA; };
class CB : virtual public CBase { int nB; };
class CD : public CA, public CB{ int nD; };
int main()
{
cout << "size of CBase " << sizeof(CBase) << endl;
cout << "size of CA " << sizeof(CA) << endl;
cout << "size of CB " << sizeof(CB) << endl;
cout << "size of CD " << sizeof(CD) << endl;
return 0;
}
32位,结果如下:
size of CBase 4
size of CA 12
size of CB 12
size of CD 24
为什么子类都会变大呢?
vs内在command Line内加入附加命令: /d1 reportAllClassLayout ,可以看到所有相关类的内存布局,对比如下(右边是虚继承后):
可以看到CBase没变,CA、CB头部都多了一个指针vbptr,指向基类CBase,CBase实例偏移到了后面,
再看CD:
CD增加了2个vbptr,指向同一个CBase。
故虚继承可以解决多个基类重复问题,但相应增加了虚基表指针的内存和指向开销。