虛函式指標和虛基類指標

2021-09-26 07:33:22 字數 1049 閱讀 5914

上述部落格給出了以下結論:

每個類都有虛指標和虛表;

如果不是虛繼承,那麼子類將父類的虛指標繼承下來,並指向自身的虛表(發生在物件構造時)。有多少個虛函式,虛表裡面的項就會有多少。多重繼承時,可能存在多個的基類虛表與虛指標;

如果是虛繼承,那麼子類會有兩份虛指標,乙份指向自己的虛表,另乙份指向虛基表,多重繼承時虛基表與虛基表指標有且只有乙份。

我覺的上述部落格中結論有些不妥,自己做了實驗進行驗證,記錄如下:

新增新虛函式

首先看一下普通繼承下,子類中定義新的虛函式會發生什麼:

子類b中沒有定義新虛函式: 

子類b中定義新虛函式: 

紅色框區域可知,新定義的虛函式和基類的虛函式儲存於乙個虛函式表,虛函式指標個數沒有改變。

再看一下虛繼承:

對比第一幅圖和這幅圖,可知虛繼承中會多乙個vbptr指標,它不是虛函式表指標。 

為什麼這裡會出現vbptr,因為虛基類派生出來的類中,虛基類的物件不在固定位置(應該是在尾部),需要乙個中介才能訪問虛基類的物件.所以子類需要有乙個vbptr,對應的table中需要有一項指向虛基類. 

虛繼承下,子類中定義新的虛函式:

對比第二幅圖和這幅圖,可知虛繼承下新增新的虛函式,會新新增新的虛函式表和虛函式指標,即基類的虛函式表中的函式是不增加的。

至此,可知:虛基類的虛函式表是不能加入新虛函式的,而普通基類的虛函式表是可以增加新的虛函式。

在子類中沒有增加新的虛函式時,虛函式表指標不變;

當子類中增加新的函式時,虛繼承的子類會增加乙個虛函式表用於儲存新的虛函式,故會多乙個虛函式表指標。

非虛多重繼承:

非虛多重繼承會將所有基類的虛函式表繼承下來。新增加的虛函式會增加到繼承順序第一的基類的虛函式表中。

多重虛繼承:

由於定義了新的虛函式而兩個基類都是虛繼承,所以需要新建虛函式表:故共有兩個基類虛函式表指標,乙個新的虛函式表指標。

鑽石繼承:

從前面實驗可知:b、c均有兩個虛函式表指標

對於d:由於虛基類的虛函式表只會存在乙份,所以d會有乙個a類的虛函式表指標,並有b、c基類的虛函式表指標。共3個指標。

虛基類指標vbptr和虛函式指標vfptr

1.問題 多重繼承 派生類物件中記憶體重複 訪問衝突 記憶體浪費 2.解決 對出現多份的資料在最近的繼承前加viture 3.虛繼承時,虛基類指標vbptr指向虛基類表vbtable,虛基類表中存放的就是資料相對於虛基類指標的偏移,從而根據偏移找到資料 vbptr vbtable vbtable 中...

虛基類 虛函式和純虛基類

首先看乙個例子 class base class child1 public base class child2 public base void main else p print 函式呼叫的時候,檢視虛表,根據p的位址首先從虛表裡面查詢要呼叫的函式 這裡呼叫child2的print 函式 ret...

C 虛函式 虛繼承 虛基類 多型 智慧型指標

簡記如下 1,什麼是虛函式 基類中被virtual關鍵字修飾的成員函式 基類希望被派生類重新定義 而不是被繼承 普通繼承 的函式 作用 實現多型。通過繼承基類中的虛函式,在子類中過載實現不同操作 2,什麼是虛繼承 虛擬繼承 d繼承自b和c,b和c都繼承自a,這時可以將b和c對a的繼承定義為虛繼承。用...