虛繼承

虛繼承是爲了消除多重繼承帶來的二義性。

以菱形繼承爲例:

class A
{
 public:
    int ma;
}
class B:public A
{
 public:
    B():A(){};
    int mb;
}
class C:public A
{
 public:
    C():A(){}
    int mc;
}
class D:public B,public C
{
 public:
    D():B(),C(){}
    int md;
}

 如下圖:B和C的父類是A,D的父類是B和C

 

D的內存佈局如下圖所示:

可以看出D的內存佈局中有兩份A的數據,那當編譯器給ma賦值時,是給B作用域下的ma還是C作用域下的ma,

這樣就會產生二義性。

要消除二義性,就需要用到虛繼承。把B類和C類繼承A類繼承都改爲虛繼承。

這時候A就成了B和C的虛基類。

這時候D的內存佈局發生變化,把A::ma移到最底部,B::和C::多了一個虛基類指針(vbptr),它指向一個vbtable,這個表中存放的是從當前位置到虛基類成員變量(這指的是ma)的偏移量。通過偏移量可以找的虛基類成員變量的位置。

用了虛繼承,我們必須在代碼中給間接基類(這裏指的A類)提供構造函數。代碼就變成了如下結構:

class A
{
 public:
    int ma;
}
class B:virtual public A
{
 public:
    B():A(){};
    int mb;
}
class C:virtual public A
{
 public:
    C():A(){}
    int mc;
}
class D:public B,public C
{
 public:
    D():B(),C(),A(){}
    int md;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章