測試環境:編譯器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...