當我們談到C++時首先會想到什么?我想大多數會想到C++的三大特性,封裝,繼承,多態。今天我們就淺談一下菱形虛擬繼承。
我們要談菱形繼承,首先要弄明白什么是菱形繼承,它的作用是什么。
菱形繼承:兩個子類繼承同一個父類,而又有子類同時繼承這兩個子類。例如:

#define _CRT_SECURE_NO_WARNINGS 1#include<iostream>using namespace std;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 d; d._a = 1; system("pause"); return 0;}分析上面代碼,運行會發生什么情況?DP8H.png)
DP8H.png)
DP8H.png)

為什么會發生這種情況呢?
兩個子類繼承了同一個基類,又有子類分別繼承了這兩個子類;當創建一個D類對象d,當調用_a時編譯器不知道要調用B中的_a,還是C中的_a。這個就是菱形繼承的二義性(java就不會存在這種情況,因為java只支持單繼承)。為了解決這個問題我們可以使用::明確給哪個_a賦值。
D d;d.B::_a = 1;d.C::_a = 2;除此上面方法,C++還提供了另一種方法-----虛繼承; //菱形繼承 D d; d.B::_a = 0; d.C::_a = 1; d._b = 2; d._c = 3; d._d = 4; //菱形虛擬繼承 D d; d._a = 1; d._b = 2; d._c = 3; d._d = 4;例如以上代碼,我們可以通過比較菱形繼承和菱形虛擬繼承:
通過比較分析菱形對象模型,我們可以看出菱形虛擬繼承在底層加了四個字節存放到A的偏移量,通過偏移量可以完美解決菱形繼承的二義性和它的另一個主要問題--數據冗余。
新聞熱點
疑難解答