C 虛函式表中的函式的索引

2021-09-26 04:32:42 字數 1332 閱讀 3773

c++的虛函式表的結構在有析構函式和沒有析構函式的情況下,還是有一定的區別的,主要區別如下:

首先是沒有析構函式的情況,**如下:

class test 

void moo()

virtual void goo()

virtual void hoo()

};

當沒有虛析構函式的情況,函式的索引是從上往下,0,1,2逐步遞增的。

當類有了虛析構函式之後,索引就變了,示例**如下:

class test 

virtual void foo() t

void moo()t

virtual void goo()

virtual void hoo()

};

有了虛析構函式之後,foo的索引是變成了2。增加了乙個析構函式,難道編譯器會生成兩個函式?於是使用clang編譯器,使用命令:clang++ -emit-llvm  -fno-discard-value-names  -w -g  -s -o virtualtable.ll virtualtable.cpp 把**編譯成ll檔案檢視位元組碼進一步檢視:

可以看到位元組碼如下,紅色字部分,可以看到果然有兩個析構函式:

@_ztv4test = linkonce_odr dso_local unnamed_addr constant * @_zti4test to i8*), i8* bitcast (void (%class.test*)* @_zn4testd2ev to i8*), i8* bitcast (void (%class.test*)* @_zn4testd0ev to i8*), i8* bitcast (void (%class.test*)* @_zn4test3fooev to i8*), i8* bitcast (void (%class.test*)* @_zn4test3gooev to i8*), i8* bitcast (void (%class.test*)* @_zn4test3hooev to i8*)] }, comdat, align 8

而且析構函式_zn4testd0ev中還呼叫了_zn4testd2ev。由此可以確定是有兩個析構函式。

也可以使用測試**測試一下虛函式的索引,**如下:

int find_function_index(cmytest* p, void* f) 

return -1;

}typedef void(* func)(void);

int main()

編譯執行**,可以發現,無論析構函式的宣告放在類的什麼位置,它在虛函式表裡的位置總在最前面,也就是索引是0。

c 中的虛函式及虛函式表

有關鍵字virtual修飾的成員函式,為了實現多型。1.虛函式表用來存放虛函式的位址,也稱虛表。2.乙個含有虛函式的類中至少有乙個虛表。3.虛表指標 二級指標,虛函式指標的指標,存放在物件模型頭部,32位系統中佔4個位元組,在64位系統中佔8個位元組。虛表指標中存放著虛表的首位址。可以通過物件例項化...

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

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

虛函式表指標,虛函式表

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