代碼1 #include <iostream> using namespace std; class A{ public: A(int _a):ma(_a){ cout<<"A()"<<endl; } ~A(){ cout<<"~A()"<<endl; } protected: int ma; }; ...
代碼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、虛函數和虛基類的開銷分析及使用指導》)。