【C++ 繼承 | 虛函數表 02】C++虛函數表剖析 ②

索引

 

 

多重繼承(無虛函數覆蓋)

下面,再讓我們來看看多重繼承中的情況,假設有下面這樣一個類的繼承關係。注意:子類並沒有覆蓋父類的函數。

class Base1
{
public:
    virtual void f() { cout << "Base1::f" << endl; }  //虛函數定義
    virtual void g() { cout << "Base1::g" << endl; }
    virtual void h() { cout << "Base1::h" << endl; }
};

class Base2
{
public:
    virtual void f() { cout << "Base2::f" << endl; }  //虛函數定義
    virtual void g() { cout << "Base2::g" << endl; }
    virtual void h() { cout << "Base2::h" << endl; }
};

class Base3
{
public:
    virtual void f() { cout << "Base3::f" << endl; }
    virtual void g() { cout << "Base3::g" << endl; }
    virtual void h() { cout << "Base3::h" << endl; }
};

class Derive :public Base1, public Base2, public Base3 //多繼承的情況——無虛繼承覆蓋
{
public:
    virtual void f1() { cout << "Derive::f1" << endl; } //虛函數定義
    virtual void g1() { cout << "Derive::g1" << endl; }
};

圖解:

對於子類實例中的虛函數表,是下面這個樣子:

我們可以看到:
1) 每個父類都有自己的虛表。
2) 子類的成員函數被放到了第一個父類的表中。(所謂的第一個父類是按照聲明順序來判斷的)

這樣做就是爲了解決不同的父類類型的指針指向同一個子類實例,而能夠調用到實際的函數。

 

多重繼承(有虛函數覆蓋)

下面我們再來看看,如果發生虛函數覆蓋的情況。

其中:D自身的虛函數與B基類共用了同一個虛函數表,因此也稱B爲D的主基類(primary base class)。

虛函數替換過程與前面描述類似,只是多了一個虛函數表,多了一次拷貝和替換的過程。

虛函數的調用過程,與前面描述基本類似,區別在於基類指針指向的位置可能不是派生類對象的起始位置,以如下面的程序爲例:

參開資料

1. 2.5 虛函數的實現及基本原理

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