C 中虛繼承的作用及底層實現原理

2021-08-14 17:25:23 字數 1264 閱讀 3159

虛繼承和虛函式是完全無相關的兩個概念。

虛繼承是解決c++多重繼承問題的一種手段,從不同途徑繼承來的同一基類,會在子類中存在多份拷貝。這將存在兩個問題:其一,浪費儲存空間;第二,存在二義性問題,通常可以將派生類物件的位址賦值給基類物件,實現的具體方式是,將基類指標指向繼承類(繼承類有基類的拷貝)中的基類物件的位址,但是多重繼承可能存在乙個基類的多份拷貝,這就出現了二義性。

虛繼承可以解決多種繼承前面提到的兩個問題:

虛繼承底層實現原理與編譯器相關,一般通過虛基類指標和虛基類表實現,每個虛繼承的子類都有乙個虛基類指標(占用乙個指標的儲存空間,4位元組)和虛基類表(不占用類物件的儲存空間)(需要強調的是,虛基類依舊會在子類裡面存在拷貝,只是僅僅最多存在乙份而已,並不是不在子類裡面了);當虛繼承的子類被當做父類繼承時,虛基類指標也會被繼承。

實際上,vbptr指的是虛基類表指標(virtual base table pointer),該指標指向了乙個虛基類表(virtual table),虛表中記錄了虛基類與本類的偏移位址;通過偏移位址,這樣就找到了虛基類成員,而虛繼承也不用像普通多繼承那樣維持著公共基類(虛基類)的兩份同樣的拷貝,節省了儲存空間。

在這裡我們可以對比虛函式的實現原理:他們有相似之處,都利用了虛指標(均占用類的儲存空間)和虛表(均不占用類的儲存空間)。

虛基類依舊存在繼承類中,只占用儲存空間;虛函式不占用儲存空間。

虛基類表儲存的是虛基類相對直接繼承類的偏移;而虛函式表儲存的是虛函式位址。

此篇部落格有關於虛繼承詳細的記憶體分布情況

補充:

1、d繼承了b,c也就繼承了兩個虛基類指標

2、虛基類表儲存的是,虛基類相對直接繼承類的偏移(d並非是虛基類的直接繼承類,b,c才是)

[cpp]view plain

copy

#include

using

namespace std;  

class a  //大小為4

;  class b :virtual

public a  //大小為12,變數a,b共8位元組,虛基類表指標4

;  class c :virtual

public a //與b一樣12

;  class d :public b, public c //24,變數a,b,c,d共16,b的虛基類指標4,c的虛基類指標

;  int main()   

C 中虛繼承的作用及底層實現原理

虛繼承和虛函式是完全無相關的兩個概念。虛繼承是解決c 多重繼承問題的一種手段,從不同途徑繼承來的同一基類,會在子類中存在多份拷貝。這將存在兩個問題 其一,浪費儲存空間 第二,存在二義性問題,通常可以將派生類物件的位址賦值給基類物件,實現的具體方式是,將基類指標指向繼承類 繼承類有基類的拷貝 中的基類...

C 多型,虛函式作用及底層實現原理

簡述c 虛函式作用及底層實現原理 c 是物件導向程式設計,其包括3項特點 1 資料抽象 介面和實現分離 2 繼承 父類和子類 3 多型 動態繫結 本文討論多型。當父類希望子類重新定義某些函式時,用virtual關鍵字宣告為虛函式。當我們使用乙個基類型別的引用或者指標,呼叫乙個虛函式時就引發動態繫結 ...

C 中虛繼承的作用

2010 09 30 15 58 01 分類 c c 程式設計基礎 舉報 字型大小訂閱 我的 書 c 虛繼承可以防止多重繼承產生的二義性問題。虛繼承,就是在被繼承的類前面加上virtual關鍵字,這時被繼承的類稱為虛基類,如下面 中的base類。虛繼承在多重繼承的時可以防止二義性。class bas...