鉆石(菱形)繼承和虛基類
阿新 • • 發佈:2019-02-03
pan 由於 test 聲明 16px pri 技術分享 color protect
鉆石(菱形)繼承
如圖,B,C繼承了A,D繼承了B,C
在這種情況下,如果D類的對象通過B、C兩個不同的作用域調用A的數據成員,將會產生兩個
不同的A的數據成員值
如下(Grandfather對應A,a是其公有數據成員,Father1,Father2對應B、C,son對應D的對象,)
可以看到有兩個不一樣的a存在,說明在賦值過程中Father1,Father2分別調用Grandfather產生兩個a
從其運行結果也可以看出來
如果son對象僅想產生一個數據成員a,則必須對Grandfather進行虛繼承
//Test1.h #include<iostream> using namespacestd; class Grandfather { public: int a; Grandfather(int _a):a(_a) { cout<<"Grandfather was built. "<<endl; } ~Grandfather(){cout<<"Grandfather was free. "<<endl;} }; class Father1 : public virtual Grandfather { public: int n; Father1(int _a) : n(_a),Grandfather(_a) { cout<<"Father1 was built. "<<endl; } ~Father1(){cout<<"Father1 was free. "<<endl;} }; class Father2 : virtual public Grandfather //virtual寫在public前後都可以 { public: int n; Father2(int _a) : n(_a),Grandfather(_a) { cout<<"Father2 was built. "<<endl; }~Father2(){cout<<"Father2 was free. "<<endl;} }; class Son : public Father1, public Father2 { public: Son(int _a):Father1(_a),Father2(_a),Grandfather(_a) { cout<<"Son was built. "<<endl; } ~Son(){cout<<"Son was free. "<<endl;} };
虛繼承就是在繼承符(public、protected、private)前或後加上virtual關鍵字,被虛繼承的類也叫虛基類
在派生類對象的創建中,
首先是虛基類的構造函數並按他們聲明順序構造。
第二批是非虛基類的構造函數按他們聲明的順序調用
第三批是成員對象的構造函數
最後是派生類自己的構造函數。
#include"Test1.h" void main() { Son son(10); son.Father1::n = 1; son.Father2::n = 2;//由於在Father1,Father2內均存在公有數據n,在對其賦值時需要加上作用域 son.Father1::a = 5; son.Father2::a = 6;//兩次賦值均對一個數據成員操作 }
可以看到兩個數據成員的地址相同。
運行結果
析構順序和構造順序相反。
鉆石(菱形)繼承和虛基類