天天看點

c++對象模型04:菱形繼承記憶體布局

菱形繼承

菱形繼承也稱為鑽石型繼承或重複繼承,它指的是基類被某個派生類簡單重複繼承了多次。這樣,派生類對象中擁有多份基類成員執行個體,這會占據更多的記憶體空間,還會引起調用基類成員時的二義性。

代碼

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; }
 
};
           

繼承類圖

c++對象模型04:菱形繼承記憶體布局

對象模型

c++對象模型04:菱形繼承記憶體布局

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實體。

繼續閱讀