1.菱形继承
代码如下:
class A
{
public:
int _a;
};
class B:public A
{
public:
int _b;
};
class C:public A
{
public:
int _c;
};
class D :public B,public C
{
public:
int _d;
};
int main()
{
D dd;
C cc;
B bb;
dd.B::_a = 1;
dd._b = 2;
dd.C::_a = 3;
dd._c = 4;
dd._d = 5;
cout <<sizeof(dd) << endl;
cout <<sizeof(bb) << endl;
cout <<sizeof(cc) << endl;
getchar();
return 0;
}
该菱形继承的简易流程图如下:
通过运行该代码以及对监视窗口的观察,dd占20个字节,而bb及cc各占8个字节。且由于D继承了C和B,导致D内有两个_a的值,分别为1,3。同一个成员出现了两个值,这样的结果就导致了菱形继承的二义性。
为了解决这个问题,我们就提出了虚继承
2.虚继承
class A
{
public:
int _a;
};
class B:virtual public A
{
public:
int _b;
};
class C:virtual public A
{
public:
int _c;
};
class D :public B,public C
{
public:
int _d;
};
int main()
{
D dd;
C cc;
B bb;
dd.B::_a = 1;
dd._b = 2;
dd.C::_a = 3;
dd._c = 4;
dd._d = 5;
cout <<sizeof(dd) << endl;
cout <<sizeof(bb) << endl;
cout <<sizeof(cc) << endl;
getchar();
return 0;
}
通过对代码的运行,我们发现了虚继承后,dd变为24个字节,bb和cc变为12个字节。他们分别都扩大了4个字节的空间。
B和C中继承的A中的_a变为了同样的值,分别都是第二次赋值后的值。
*虚继承--解决了菱形继承的二义性和数据冗余问题
1.虚继承解决了在菱形继承体系中子类对象包含多份父类对象的数据冗余及浪费空间的问题。
2.虚继承体系看起来很复杂,在实际应用中我们通常不会定义如此复杂的继承体系。一般不到万不得已都不要用菱形结构的虚继承体系结构,因为使用虚继承解决数据冗余问题也带来了性能上的损耗。