詳談C 虛函式表那回事(一般繼承關係)

2021-07-14 20:23:55 字數 2405 閱讀 1708

沿途總是會出現關於c++虛函式表的問題,今天做一總結:

1.什麼是虛函式表:

虛函式(

virtual function

)是通過一張虛函式表(

virtual table

)來實現的。簡稱為

v-table

。在這個表中,主是要乙個類的虛函式的位址表,這張表解決了

繼承、覆

蓋的問題,\

保證其容真實反應實際的函式。這樣,在有虛函式的類的例項中這個表被分配在了這個例項的記憶體中,所以,當我們用父類的指標來

操作乙個子類的時

候,這張虛函式表就顯得

由為重要了,它就像乙個地圖一樣,指明了實際所應該呼叫的函式。

看乙個例子:

#pragma once

//c++中的虛函式的作用主要是實現了多型的機制

//通過base的例項來得到虛函式表

class base

virtual void g()

virtual void h()

};typedef void(*fun)(void);

void test()

}

結果截圖:

關於**中函式指標,已加說明。通過對物件位址的強轉輸出得到虛函式表的位址,即所謂的虛表指標內容:

由於是兩次進函式,故位址有變,但是道理沒錯!虛表指標就是 _vfptr;

2.無虛函式覆蓋的一般繼承:(虛表)

看**:

#pragma once

//一般繼承(無虛函式覆蓋)

class base

virtual void g()

virtual void h()

};//無覆蓋 公有繼承

class derive :public base

virtual void g1()

virtual void h1()

};void test()

請看,在此繼承中,子類沒有過載任何父類函式,則子類的函式表在vs2013下是這樣的:

發現沒,d是乙個子類物件,子類繼承父類,虛函式表中盡然只有父類的虛函式位址,子類自己的虛函式都沒有顯示,這是不可能的啊

很顯然,這可能就是編譯器的bug,但其實,真實的子類虛函式表是這樣的:

可以看出:

1》虛函式按照宣告順序存放於虛表中;

2》子類虛函式在基類虛函式之後;

3.有虛函式覆蓋的一般繼承:(虛表)

看**:

#pragma once

//有虛函式覆蓋的一般繼承

//有覆蓋是必然的,否則,虛函式將失去作用

class base

virtual void g()

virtual void h()

};//乙個覆蓋 公有繼承

class derive :public base

//注意:這裡函式覆蓋了基類的相同函式;

virtual void g1()

virtual void h1()

};void test()

執行結果:

很明顯基類物件呼叫基類的函式,子類物件,「

好像」也呼叫子類函式,好像的原因看下面:

分析:1》覆蓋的虛函式f()存放在虛表中原來父類虛函式的位置。

2》其他函式依舊

3》這裡還是同樣沒有顯示子類虛函式存放在表中,個人堅持認為,是編譯器的bug,真實展示如下:

可見:覆蓋的虛函式f()存放在虛表中原來父類虛函式的位置,這也是基類物件*p訪問 f() 時,訪問的直接是子類的虛函式,完美的體現了多型;

有關多型,請在見另一篇部落格:

另外有關多重繼承,見下篇;

賜教!

詳談C 虛函式表那回事(多重繼承關係)

1.無虛函式覆蓋的多重繼承 pragma once 無覆蓋,多重繼承 class base1 virtual void g virtual void h class base2 virtual void g virtual void h class base3 virtual void g virt...

詳談C 虛函式表那回事(多重繼承關係)

1.無虛函式覆蓋的多重繼承 pragma once 無覆蓋,多重繼承 class base1 virtual void g virtual void h class base2 virtual void g virtual void h class base3 virtual void g virt...

C 虛函式表研究 (一) 單繼承

c 虛函式表研究 一 單繼承 本文研究單繼承情況下,c 物件的虛函式表的具體情況。所用的編譯器為vc6.0。假設有兩個類a,b,其中b由a派生出來,a含有虛函式fun1,b含有虛函式fun2 a 的定義如下 b的定義如下 測試的 如下 測試 說明 虛函式表指標 int b 虛函式表位址 int b ...