虛函式 多重繼承 動態繫結

2021-09-12 16:45:55 字數 1286 閱讀 1903

class a ;

class b : public a ;

class c: public b ;

假設我們定義乙個類b的物件。由於bobject是類b的乙個物件,故bobject包含乙個虛表指標,指向類b的虛表。

int main() 

int main() 

int main() 

程式在執行p->vfunc1()時,會發現p是個指標,且呼叫的函式是虛函式,接下來便會進行以下的步驟。 

首先,根據虛表指標p->__vptr來訪問物件bobject對應的虛表。雖然指標p是基類a*型別,但是*__vptr也是基類的一部分,所以可以通過p->__vptr可以訪問到物件對應的虛表。 

然後,在虛表中查詢所呼叫的函式對應的條目。由於虛表在編譯階段就可以構造出來了,所以可以根據所呼叫的函式定位到虛表中的對應條目。對於 p->vfunc1()的呼叫,b vtbl的第一項即是vfunc1對應的條目。 

最後,根據虛表中找到的函式指標,呼叫函式。從圖3可以看到,b vtbl的第一項指向b::vfunc1(),所以 p->vfunc1()實質會呼叫b::vfunc1()函式。

如果p指向類a的物件,情況又是怎麼樣?

int main() 

當aobject在建立時,它的虛表指標__vptr已設定為指向a vtbl,這樣p->__vptr就指向a vtbl。vfunc1在a vtbl對應在條目指向了a::vfunc1()函式,所以 p->vfunc1()實質會呼叫a::vfunc1()函式。

可以把以上三個呼叫函式的步驟用以下表示式來表示:

(*(p->__vptr)[n])(p)

可以看到,通過使用這些虛函式表,即使使用的是基類的指標來呼叫函式,也可以達到正確呼叫執行中實際物件的虛函式。 

我們把經過虛表呼叫虛函式的過程稱為動態繫結,其表現出來的現象稱為執行時多型。動態繫結區別於傳統的函式呼叫,傳統的函式呼叫我們稱之為靜態繫結,即函式的呼叫在編譯階段就可以確定下來了。

那麼,什麼時候會執行函式的動態繫結?這需要符合以下三個條件。

如果乙個函式呼叫符合以上三個條件,編譯器就會把該函式呼叫編譯成動態繫結,其函式的呼叫過程走的是上述通過虛表的機制。

封裝,繼承,多型是物件導向設計的三個特徵,而多型可以說是物件導向設計的關鍵。c++通過虛函式表,實現了虛函式與物件的動態繫結,從而構建了c++物件導向程式設計的基石。

c 虛函式 多重繼承

如果類有虛函式,則類會有預設的乙個指標成員指向虛函式表 可能儲存在全域性區 的位址,指標占用4個位元組。虛函式 easytest.cpp 定義控制台應用程式的入口點。include stdafx.h include using namespace std class a class b public...

多重繼承與虛函式表

from 一 多重繼承 1 include iostream using namespace std class b1void f1 class b2void f2 class b3void f3 class d public b1,public b2,public b3virtual void v...

多重繼承虛函式表分析

project100.cpp 此檔案包含 main 函式。程式執行將在此處開始並結束。include pch.h include using namespace std 基類1 class base1 virtual voidg 基類2 class base2 virtual voidi 子類 cl...