大家都知道c++的虛函式前必須加virtual,但如果一連串的繼承下來,有的忘了加virtual會出現什麼情況呢?為了滿足我的好奇心,做了點實驗然後有了本文,僅僅是好玩,沒有啥實際意義。本文只給出vs2005的情況
首先,如果是單一類,沒加virtual的話那麼好辦,直接call a::fun,非static函式call之前push物件指標就ok了。所以此類函式的呼叫與普通函式沒啥兩樣,用點小trick,可以把類成員函式做多執行緒的執行緒函式。如果是virtual的話,需要通過vtbl來呼叫,vc編譯器把類物件開頭四個位元組來作為vtbl位址,呼叫虛函式只需確定函式偏移即可。例子:class a的乙個虛函式fun,a為類物件指標,呼叫a->fun(),生成的彙編**為:
mov eax,dword ptr [a]
mov edx,dword ptr [eax]
mov esi,esp
mov ecx,dword ptr [a]
mov eax,dword ptr [edx]
call eax
接著考慮有繼承的情況,經過一些測試,發現編譯器某函式是否是virtual的方法是,通過呼叫函式的指標型別,然後查詢該類,以及該類的所有父類的所有虛函式,只要發現有此函式就認定為virtual的,也就是說必須對此函式進行動態binding,通過vtbl來呼叫此函式,否則直接用該指標類的成員函式。舉個例子,類a,b,c,b是c的父類,a是b的父類,a,b,c中都定義了函式fun,其中c中的fun是virtual,a,b中沒加virtual,那麼有如下語句,b* b=new c;b->fun(),那麼呼叫的是b的fun。
類成員函式呼叫的細節
class concrete void printerror private int val void main 為什麼會出現這種情況呢?原來是,函式定義的時候,就一直存在了。即無聊是否 例項化了乙個物件,print 這個函式,都是存在的。所以 pc print 是可以找到函式的入口的。只是這時候,...
c 類的成員函式的呼叫
我知道c 有乙個虛函式列表,物件有指向虛函式列表的指標,對於有虛函式的類物件呼叫虛函式時通過虛函式列表裡面的指標實現的。但是對於普通的非虛函式是怎麼實現呼叫的呢 是怎麼找到非虛函式的入口位址?好像類物件裡面只有類的一些資料成員。求解惑 求詳細的記憶體層次的變化 2013 09 10 20 39 提問...
通過函式指標呼叫類成員函式的方法
通過函式指標呼叫乙個函式的時候,此函式必須有具體的位址,因此當呼叫乙個類成員函式的時候,此成員函式必須宣告為static,即靜態成員函式,這樣就能通過函式指標獲取到成員函式的位址,進而呼叫。關於靜態成員函式 編譯器在編譯乙個普通成員函式時,會隱式地增加乙個形參this,並把當前物件的位址賦值給thi...