虛函式表再學習

2021-07-04 17:35:43 字數 1701 閱讀 6400

測試環境:編譯器gcc,環境win7,64位系統

參考:結論:1. 虛函式指標儲存在類其他成員之前

2. 基類的虛函式表、子類的虛函式表是分別存放的

3. 子類虛函式表中儲存的內容依次為:繼承自基類的虛函式(按宣告順序存放)、子類自己的虛函式(按宣告順序存放);

4. 即使子類沒有自己的虛函式,他仍然會建立乙個虛函式指標以及虛函式表,虛函式表內容與父類相同,但存放位址不同。

5. 當有覆蓋發生時,子類虛函式表更新,基類不變。

首先是驗證**:

#include using namespace std;

class a {

virtual void a(){cout << "a:a" <

驗證:結論一:虛函式指標儲存在類其他成員之前

看這裡:

cout<

cout<

....

pfun = (fun)*(int*)*(int*)(&aa);

pfun();

pfun = (fun)*((int*)*(int*)(&aa)+1);

pfun();

pfun = (fun)*((int*)*(int*)(&aa)+2);

pfun();

pfun = (fun)*((int*)*(int*)(&aa)+3);

pfun();

pfun = (fun)*((int*)*(int*)(&aa)+4);

pfun();

結論二:基類的虛函式表、子類的虛函式表是分別存放的

ap、aap、aaap分別代表基類、子類、孫子類的虛函式表位址,得證;

結論三:子類虛函式表中儲存的內容依次為:繼承自基類的虛函式(按宣告順序存放)、子類自己的虛函式(按宣告順序存放);

將子類中覆蓋基類的a()方法注釋掉,執行截圖如下:

框內為子類虛函式表的存放內容:依次是基類的三個方法按宣告順序存放,子類兩個方法按宣告順序存放;

結論四:即使子類沒有自己的虛函式,他仍然會建立乙個虛函式指標以及虛函式表,虛函式表內容與父類相同,但存放位址不同。

將子類**修改為,實際就是注釋掉所有自己的方法:

看橙色框內的內容:位址是不相同的,但列印出來的內容是相同的(無覆蓋)。

結論五:當有覆蓋發生時,子類虛函式表更新,基類不變。

修改子類**:

父類的虛函式表內容沒有改變,子類虛函式表原本為基類的a( )方法,替換為了子類的a( )方法。

以上五個結論得到驗證。

虛函式表指標,虛函式表

對c 了解的人都應該知道虛函式 virtual function 是通過一張虛函式表 virtual table 來實現的。簡稱為v table。在這個表中,主是要乙個類的虛函式的位址表,這張表解決了繼承 覆蓋的問題,保證其容真實反應實際的函式。這樣,在有虛函式的類的例項中這個表被分配在了 這個例項...

虛函式表和虛函式表的指標

有虛函式的類都有乙個虛函式表,它是實現多型的關鍵。虛函式表可以繼承,如果子類沒有重寫虛函式,那麼子類虛函式表中仍然會有該函式的位址,只不過這個位址指向的是基類的函式實現。如果子類重寫了相應的虛函式,那麼虛函式表中的位址就會改變,指向自身的函式實現。如果派生類中有自己的虛函式,那麼虛函式表中會新增該項...

虛函式之虛函式表

多型性可分為兩類 靜態多型和動態多型。函式過載和運算子過載實現的多型屬於靜態多型,動態多型性是通過虛函式實現的。每個含有虛函式的類有一張虛函式表 vtbl 表中每一項是乙個虛函式的位址,也就是說,虛函式表的每一項是乙個虛函式的指標。沒有虛函式的c 類,是不會有虛函式表的。兩張圖 簡單例子 inclu...