菱形继承在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;虽然相对而言过程较为繁琐,带来了性能上的损耗,但是解决了 菱形继承的二义性和数据冗余。