C 虛函式的實現機制

2022-03-13 04:43:08 字數 2335 閱讀 7468

一.什麼是虛函式

虛函式是在類中由virtual關鍵字宣告的成員函式,並且每乙個含有虛函式的類都至少有乙個與之對應的虛函式表,其中存放著該類所有虛函式對應的函式指標

在基類中進行如下定義:

virtual void show() //由於有virtual修飾所以是虛函式

void show()//雖然和前面宣告的show虛函式同名,但不是虛函式

所有虛函式位址都會存放在所屬類的虛函式表vtbl中,另外在基類中宣告為虛函式的成員方法,達到子類是仍然是虛函式,即使子類中重新定義基類虛函式時未使用virtual修飾,該函式位址仍會放在子類的虛函式表vtbl中

二.虛函式表是如何構造和繼承的?1)基類虛函式表的構造:

首先在基類宣告中找到所有虛函式,按照其宣告順序編碼,然後按照此宣告順序為基類建立乙個虛函式表,其內容就是指向這些虛函式的函式指標,按照虛函式宣告的順序將這些虛函式的位址填入虛函式表中,例如若show放在虛函式宣告的第二位,則在虛函式表中也放第二位

2)子類虛函式表的構建和繼承:

首先將基類的虛函式表複製到該子類的虛函式表指標中,若子類重寫了基類的虛函式show,則將子類的虛函式表存放show的函式位址更新未重寫後函式的函式指標(未重寫前存放的是子類的show虛函式的函式位址),若子類增加了一些虛函式的宣告,則將這些虛函式的位址加到該類虛函式表的後面

三.虛函式的呼叫過程/虛函式表是如何訪問的?

基類     base::virtualvoid show();              (1)

子類     extend::virtualvoid show();             (2)

extern ext;

base*pbase=&ext;

pbase->show();

當指向pbase->show()時,要觀察show在base基類中宣告的是虛函式還是非虛函式,若為虛函式將使用動態聯編(使用虛函式表決定如何呼叫函式),若為非虛函式則使用靜態聯編(根據呼叫指標pbase的型別來確定呼叫哪個類的成員函式),此處show為虛函式,首先由於檢查到pbase指標型別所指的類base中show定義為虛函式,因此找到pbase所指物件(有可能是base型別也有可能是extern型別),訪問物件得到該物件的所屬類虛函式位址表,其次,查詢show在base類中宣告的位置以此找到其在show在base類中所有虛函式宣告中的位序,然後到pbase所指物件的所屬類的虛函式表中訪問該位序的函式指標,從而得到要執行的函式

當執行pbase->show();時首先到base中檢視show(),發現其為虛函式,然後訪問pbase指向的ext物件,在物件中得到extend類的虛函式表,在base類宣告中找到show()宣告的位序0,訪問extend類的虛函式表的位置0,得到show的函式位址。注意若只有基類定義了virtual void show();而子類未重寫virtual void show();即上面的函式(2),則extend虛函式表中的位序0中存放的位址仍然是base類中定義的virtual void show()函式,而若extend類中重寫了base類中的virtual void show()方法,則extend的虛函式表中位序0的函式位址將被更新為extend中新重寫的函式位址。從而呼叫pbase->show()時將產生多型的現象。

總結:當呼叫pbase->show();時,執行的步驟:

1.判斷base類中show是否為虛函式。

2.若不是虛函式則找到pbase所指向的物件所屬類base。執行base::show()。若是虛函式則執行步驟3.

3.訪問pbase所指物件的虛函式表指標得到pbase所指物件所在類的虛函式表。

4.查詢base中show()在宣告時的位序為x,到步驟3得到的虛函式表中找到位序x,從而得到要執行的show的函式位址。

5.根據函式位址和base中宣告的show的函式型別(形參和返回值)訪問位址所指向的函式。

無論pbase指向哪種型別的物件,只要能夠確定被調函式在虛函式中的偏移值,待執行時,能夠確定具體型別,並能找到相應vptr了,就能找出真正應該呼叫的函式。

C 虛函式實現機制

看完之後,對c 中的虛函式實現機制算的上是恍然大悟,但是個人感覺博文中有幾點不足之處,現在一一枚舉,以下語言僅僅代表個人看法 1.定位虛表的方式 大家都知道含有虛函式的類的例項裡面前4個位元組是虛函式指標占用的記憶體,裡面填充的是虛函式表的位址號。原博文中通過乙個long型別的物件取得前四個位元組的...

c 虛函式實現機制

1 c 實現多型的方法 其實很多人都知道,虛函式在c 中的實現機制就是用虛表和虛指標,但是具體是怎樣的呢?從more effecive c 其中一篇文章裡面可以知道 是每個類用了乙個虛表,每個類的物件用了乙個虛指標。具體的用法如下 class a class b public a a,b的實現省略 ...

C 虛函式實現機制

c 中的虛函式的作用主要是實現了多型的機制。關於多型,簡而言之就是用父型別別的指標指向其子類的例項,然後通過父類的指標呼叫實際子類的成員函式。對c 了解的人都應該知道虛函式 virtual function 是通過一張虛函式表 virtual table 來實現的。簡稱為v table。在這個表中,...