菱形虛擬繼承的深入剖析

2021-07-26 23:54:06 字數 1621 閱讀 2161

繼承是物件導向語言的一大特性,在c++中既有單繼承,當然也會存在多繼承。那麼多繼承是怎麼實現的及多繼承的一些缺點,將是這篇部落格想要說的內容。

多繼承最典型的乙個例子就是菱形繼承,那什麼又是菱形繼承呢?就是有兩個子類分別繼承乙個父類,而有存在乙個子類同時這兩個子類。圖示如下。

當我們模擬出菱形繼承想給a賦值時,就會發現乙個問題,我們到底是從哪個類去訪問的baseclass中的a?這時就會產生二義性。也就是說在記憶體中會出現兩個baseclass,結構圖如下。

**執行後調監視視窗如上,可明顯看到d中存在了兩個a,這也會存在資料冗餘的問題。那怎麼去解決這個問題?此時,c++又提出了另乙個新概念——虛擬繼承。虛擬繼承使得在繼承間接共同基類的時候只保留乙份成員。接下來的篇幅將會說明虛擬繼承的實現。

class a

;class b : virtual

public a

;class c : virtual

public a

;class d : public b, public c

;int main()

執行上述**後,在記憶體中會出現以下的情形,如下圖。

原來大小為20的d如今變成了24,按理說當我們採用了虛擬繼承,解決了資料冗餘問題,所佔的空間應該也會變小,但如今反而變大了,這是怎麼回事呢?

我們在細看第一行和第三行,發現了這兩個數字比較接近,仔細看更像是乙個位址。於是,在記憶體中檢視會發現如下圖所示的情形。

在這兩個記憶體緊挨著的地方,出現了乙個「14」和「0c」,也就是說在這個地方存了這兩個數字。那麼我們就可以猜測一下,在虛擬繼承中,菱形繼承的結構是如下圖的。

baseclass並不是按照我們所想象那樣存在最上面的,而是存放在最底下,而原來存baseclass的地方存了兩個「數字」。仔細觀察,不難發現這兩個數字是距離baseclass的位移,也就是我們所說的偏移量。

其實,講到這裡的時候,大家應該也就明白了,在虛擬繼承中是通過儲存基類的偏移量來解決資料冗餘的問題,以空間換時間解決菱形繼承存在的問題。

菱形繼承 菱形虛擬繼承

菱形繼承 鑽石繼承 模型 拿如下 舉例 class person class student public person class teacher public person class graduate public student,public teacher void test 當派生類gr...

菱形虛擬繼承

菱形繼承在c 繼承中是一種複雜的繼承關係,存在著二義性和資料冗餘的問題,而菱形虛擬繼承則是為了解決菱形繼承所存在的問題。為了 菱形虛擬繼承如何解決該問題,我先建立個乙個較為簡單的菱形繼承模型。下面分別是菱形繼承和菱形虛擬繼承的 實現 菱形繼承 include includeusing namespa...

複雜的菱形繼承及菱形虛擬繼承

乙個子類只有乙個直接父類時稱這個繼承關係為單繼承 乙個子類有兩個或兩個以上的直接父類時稱這個繼承方式為多繼承 菱形繼承是多繼承的一種特殊情況 菱形繼承的問題 1.冗餘 2.二義性 class person class student public person class teacher publi...