菱形繼承
菱形繼承也稱為鑽石型繼承或重複繼承,它指的是基類被某個派生類簡單重複繼承了多次。這樣,派生類對象中擁有多份基類成員執行個體,這會占據更多的記憶體空間,還會引起調用基類成員時的二義性。
代碼
class B
{
public:
int ib;
public:
B(int i=1) :ib(i){}
virtual void f() { cout << "B::f()" << endl; }
virtual void Bf() { cout << "B::Bf()" << endl; }
};
class B1 : public B
{
public:
int ib1;
public:
B1(int i = 100 ) :ib1(i) {}
virtual void f() { cout << "B1::f()" << endl; }
virtual void f1() { cout << "B1::f1()" << endl; }
virtual void Bf1() { cout << "B1::Bf1()" << endl; }
};
class B2 : public B
{
public:
int ib2;
public:
B2(int i = 1000) :ib2(i) {}
virtual void f() { cout << "B2::f()" << endl; }
virtual void f2() { cout << "B2::f2()" << endl; }
virtual void Bf2() { cout << "B2::Bf2()" << endl; }
};
class D : public B1, public B2
{
public:
int id;
public:
D(int i= 10000) :id(i){}
virtual void f() { cout << "D::f()" << endl; }
virtual void f1() { cout << "D::f1()" << endl; }
virtual void f2() { cout << "D::f2()" << endl; }
virtual void Df() { cout << "D::Df()" << endl; }
};
繼承類圖
對象模型
D類對象記憶體布局中,圖中青色表示b1類子對象執行個體,黃色表示b2類子對象執行個體,灰色表示D類子對象執行個體。從圖中可以看到,由于D類間接繼承了B類兩次,導緻D類對象中含有兩個B類的資料成員ib,一個屬于來源B1類,一個來源B2類。這樣不僅增大了空間,更重要的是引起了程式歧義:
D d;
d.ib =1 ; //二義性錯誤,調用的是B1的ib還是B2的ib?
d.B1::ib = 1; //正确
d.B2::ib = 1; //正确
盡管我們可以通過明确指明調用路徑以消除二義性,但二義性的潛在性還沒有消除,我們可以通過虛繼承來使D類隻擁有一個ib實體。