擁有虛函式覆蓋的菱形繼承及菱形虛擬繼承

2021-07-27 01:50:39 字數 1770 閱讀 2098

在之前的部落格中有簡單的介紹了一下:沒有虛函式的菱形繼承。此篇部落格將對菱形繼承進行公升級,介紹有虛函式的菱形繼承。

舉乙個簡單的例子:

#includeusing namespace std;

class aa

virtual void fun2()

virtual void fun3()

protected:

int _aa;

};class bb : public aa

virtual void fun2()

protected:

int _bb;

};class cc : public aa

virtual void fun2()

protected:

int _cc;

};class dd : public bb, public cc

virtual void fun2()

virtual void fun4()

protected:

int _dd;

};typedef void (*func)();

void printvtable(int* vtable)

}int main()

監視視窗能夠看出菱形繼承裡面的記憶體布局如下:

通過監視視窗我們能夠看到dd中有繼承的類bb和類cc,其中bb和cc中都各自包括乙個虛表指標,且指標的位址不相同,則兩個類各自存在乙個虛函式表。同時我們也能夠看到菱形繼承中,dd中存在兩個成員_aa,這就存在問題,當我們想要訪問_aa時,編譯器不知道我們想要訪問的是哪乙個變數,這就說明菱形繼承存在二義性和資料冗餘。那麼如何解決菱形繼承所存在的問題呢?

菱形虛擬繼承解決了菱形繼承中存在的二義性和資料冗餘。虛擬繼承就是增加虛基表和偏移量,將bb和cc繼承改為虛擬繼承。

**如下:

#includeusing namespace std;

class aa

virtual void fun2()

virtual void fun3()

protected:

int _aa;

};class bb : virtual public aa

virtual void fun2()

protected:

int _bb;

};class cc : virtual public aa

virtual void fun2()

protected:

int _cc;

};class dd : virtual public bb, virtual public cc

virtual void fun2()

virtual void fun4()

protected:

int _dd;

};typedef void (*func)();

void printvtable(int* vtable)

}int main()

通過監視視窗,我們可以看到以下現象:

菱形虛擬繼承比菱形繼承的dd中多存在乙個指標_vfptr,該指標指向偏移量。至此,菱形繼承消除了其存在的二義性及資料冗餘。

菱形繼承和菱形虛繼承

繼承是c 的一大特點,我們通過菱形繼承和菱形虛繼承對繼承進行進一步的分析。菱形繼承 建立乙個基類a讓b1和b2公有繼承於它,讓c公有繼承b1和b2。class a a int a class b1 public a b1 int b1 class b2 public a b2 int b2 clas...

帶有虛函式的菱形繼承和帶有虛函式的菱形虛繼承

對於某些函式來說,基類希望它的派生類定義適合自身的版本,此時基類就將這些函式宣告為虛函式。在存在虛函的類,建立物件時會產生虛表指標,虛表指標指向乙個虛表,這時就可以通過虛表訪問自己定義的函式。通過下面兩種繼承進行分析 帶有虛函式的菱形繼承 以下圖的模型為例進行分析 我們觀察c類物件在記憶體中的結構 ...

菱形繼承的虛函式表

虛函式 類的成員函式前面加virtual 虛函式的主要作用就是實現多型 那麼多型 顧名思義就是一種事物的多種形態。c 中,指具有不同功能的函式可以用同乙個函式名,這樣可以用乙個函式名呼叫不同內容的函式。虛函式表 虛表 通過一片連續的位址來儲存虛函式的位址 菱形繼承舉例 說明 若子類中有虛函式,而所繼...