<十>關於菱形繼承
阿新 • • 發佈:2022-11-30
程式碼1
#include <iostream> using namespace std; class A{ public: A(int _a):ma(_a){ cout<<"A()"<<endl; } ~A(){ cout<<"~A()"<<endl; } protected: int ma; }; class B : public A{ public: B(int _b):A(_b),mb(_b){ cout<<"B()"<<endl; } ~B(){ cout<<"~B()"<<endl; } protected: int mb; }; class C : public A{ public: C(int _c):A(_c),mc(_c){ cout<<"C()"<<endl; } ~C(){ cout<<"~C()"<<endl; } protected: int mc; }; class D : public B, C{ public: D(int _d):B(_d),C(_d),md(_d){ cout<<"D()"<<endl; } ~D(){ cout<<"~D()"<<endl; } protected: int md; }; int main(){ D d(100); return 0; } //程式碼執行順序 A() B() A() C() D() ~D() ~C() ~A() ~B() ~A()
D的記憶體結構
發現有重複的 資料 ma
為了解決上面的問題,引入虛繼承
程式碼2
#include <iostream> using namespace std; class A{ public: A(int _a):ma(_a){ cout<<"A()"<<endl; } ~A(){ cout<<"~A()"<<endl; } protected: int ma; }; class B : virtual public A{ public: B(int _b):A(_b),mb(_b){ cout<<"B()"<<endl; } ~B(){ cout<<"~B()"<<endl; } protected: int mb; }; class C : virtual public A{ public: C(int _c):A(_c),mc(_c){ cout<<"C()"<<endl; } ~C(){ cout<<"~C()"<<endl; } protected: int mc; }; class D : public B, C{ public: D(int _d):A(_d),B(_d),C(_d),md(_d){ cout<<"D()"<<endl; } ~D(){ cout<<"~D()"<<endl; } protected: int md; }; int main(){ D d(100); return 0; } //執行結果 A() B() C() D() ~D() ~C() ~B() ~A() //A的構造有D 來完成 B和C下面有各自的vbptr 定位得基類資料
虛繼承用來解決多重繼承中遇到的多份資料的問題
虛擬繼承在一般的應用中很少用到,所以也往往被忽視,這也主要是因為在C++中,多重繼承是不推薦的,也並不常用,而一旦離開了多重繼承,虛擬繼承就完全失去了存在的必要(因為這樣只會降低效率和佔用更多的空間,關於這一點,我自己還沒有太多深刻的理解,有興趣的可以看網路上白楊的作品《RTTI、虛擬函式和虛基類的開銷分析及使用指導》)。