菱形继承在C++继承中是一种复杂的继承关系,存在着二义性和数据冗余的问题,而菱形虚拟继承则是为了解决菱形继承所存在的问题。为了探讨菱形虚拟继承如何解决该问题,我先建立个一个较为简单的菱形继承模型。下面分别是菱形继承和菱形虚拟继承的代码实现:
//菱形继承
#include<iostream>
#include<windows.h>
using namespace std;
class AA
{
public:
int _aa;
};
class BB : public AA
{
public:
int _bb;
};
class CC : public AA
{
public:
int _cc;
};
class DD : public BB , public CC
{
public:
int _dd;
};
int main()
{
DD d;
d.BB::_aa = 0;
d.CC::_aa = 1;
d._bb = 2;
d._cc = 3;
d._dd = 4;
cout << sizeof(DD) << endl;
system("pause");
return 0;
}
//菱形虚拟继承
#include<iostream>
#include<windows.h>
using namespace std;
class AA
{
public:
int _aa;
};
class BB : virtual public AA
{
public:
int _bb;
};
class CC : virtual public AA
{
public:
int _cc;
};
class DD : public BB, public CC
{
public:
int _dd;
};
int main()
{
DD d;
d._aa = 1;
d._bb = 2;
d._cc = 3;
d._dd = 4;
cout << sizeof(DD) << endl;
system("pause");
return 0;
}
菱形虚拟继承解决了菱形继承的二义性和数据冗余,从上图的对比我们可以看出,_aa在菱形继承中赋值时比较麻烦并且有两个不同的值,也就是二义性,而在菱形虚拟继承中可以定义一次,而派生类BB、CC访问基类AA时,通过他们所存的地址--找到与_aa的 偏移量--调用_aa;虽然相对而言过程较为繁琐,带来了性能上的损耗,但是解决了 菱形继承的二义性和数据冗余。