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。在這個表中,主是要乙個類的虛函式的位址表,這張表解決了繼承 覆蓋的問題,保證其容真實反應實際的函式。這樣,在有虛函式的類的例項中這個表被分配在了 這個例項...