Visual C 對虛函式過載的詭異布局

2021-05-22 16:09:39 字數 927 閱讀 9801

毫不令人驚訝的是,c++又給了我乙個驚訝!

對於被過載的虛函式(overloaded virtual member functions),visual c++ 並不會依照它們宣告的順序排布在虛表中。

一組(同名的)過載虛函式會按照它們宣告的逆序依次排布在一起,而組與組之間的順序,是由組內最先出現的那個函式宣告的位置決定的,越先宣告,該組越靠前。

試看下面這個例子:

#include

struct base ; 

struct some : public base

virtual void b()

virtual void a(int)

virtual void b(int) };

int

main()

some物件中的vtable的順序是這樣:some::a(int), some::a(), some::b(int), some::b()。

用vc(vs2005)跑這段程式來驗證一下,輸出是:

00401140,00401150,00401160,00401170

com的二進位制標準要求介面方法按照宣告順序排列在虛表中,vc的做法和com矛盾,所以不要在com介面中使用過載虛函式。微軟的說法是,這種行為是當初vc的設計決定的,沒法兒改了,很多老**依賴這種行為。

而g++在處理這個問題上的做法是符合com規範的,當然也符合了我們的直覺,它的輸出是:

00000009,00000001,0000000d,00000005

注意,由於不同編譯器對指向虛擬成員函式的指標的實現各有不同,所以vc和g++輸出的內容差別很大。不用去管它,我們只要給這4個值排個序就足以判斷出它們在虛表中的位置。

最後要奉勸大家的是,即使想通過只暴露純抽象基類的方法來讓二進位制c++模組跨編譯器,你也要相當小心!

虛函式和過載

面試必考。1 include 2 class cbase39 10void g float x 11 14 1516 繼承類 cderived 17class cderived public cbase 1824 public 25 26void g float x 27 30 3132 33voi...

對虛函式 虛表的認識

虛函式 實現多型的機制,多型就是用父型別的指標指向其子類的例項,然後通過父類的指標呼叫實際子類的成員函式。讓父類的指標有 多種形態 一種泛型技術。關鍵字 virtual 虛函式表 此表中,主要是乙個類的虛函式的位址表,這張表解決了繼承 覆蓋的問題,保證其內容真實反映實際的情況。在c 標準規格說明書中...

函式過載和虛函式繼承

include class cbase void g float x class cberived public cbase void g float x void main 輸出結果 cberived f 函式列印 整數 3 cberived g 函式列印 浮點小數 6.000000 cberiv...