c 中虛函式的實現詳解

2022-10-01 18:12:11 字數 2040 閱讀 2574

前言

c++ 分為編譯時多型和執行時多型。執行時多型依賴於虛函式,大部分人或許聽說過虛函式是由虛函式表+虛函式指標實現的,但,真的是這樣嗎?雖然 c++ 規範有著複雜的語言細節,但底層實現機制卻任由編譯器廠商想象程式設計客棧。(沒準某種特殊的處理器電路結構原生支援虛函式,沒準這個處理器壓根不是馮紐曼型,或者將來廠商發明了比虛函式表更有效率的資料結構。)

虛函式表

封裝把例項的資料和操作結合在了一起,但例項本身只有資料,沒有函式,同乙個類的函式是共享的。我們通過乙個例子來間接證明這一點

class base1

};base1 b1;

cout << sizeof(b1) << endl;

列印4如果類中有虛函式,則會在物件中加入乙個虛函式指標,該指標指向乙個虛函式表,表中是各個虛函式的位址。

+--------+ +---------+

| pvtbl |------>| vfunc1 |

+--------+ +---------+

| data1 | | vfunc2 |

+--------+ +---------+

| ... | | ... |

當子類繼承父類時,會依次覆蓋虛函式表中的各個項,如果子類沒有重寫某項,那該項就保留。當例項化物件後,虛函式指標就作為乙個隱藏資料存在於例項中。如果通過父類指標呼叫普通成員函式,由於普通函式和型別繫結在一起,所以仍會呼叫父類成員函式;如果通過父類指標呼叫虛函式,則會通過物件的虛指標找到虛函式表(即子類的虛函式表),定位虛函式項,實現多型。

原理是不是很簡單?c++ 就是通過這種看似原始的方式實現高階抽象。以上是編譯器的通用做法,我手上的 visual studio 2013 編譯器就是這麼做的,為了提高效能,vs 保證虛函式指標存在於物件例項中最前面位置(歷史上也有編譯器不這麼做,好像是 borland 的?)。

visual studio 2013 中的實現

來乙個例子(能這麼寫是因為我已知了 visual studio 2013 編譯後物件的記憶體布局)

#include

using namespace std;

class base

virtual void func2()

virtual void func3()

};class derived: public base

virtual void func3()

};int main()

cout << endl;

derived d;

int** pvirtualtable2 = (int**)&d;

cout << "derived object vtbl address: " << pvirtualtable2[0] << endl;

cout << "function in virtual table" << endl;

for (int i = 0; (base::func)pvirtualtable2[0][i] != null; ++i)

cout << endl;

}列印base object pvtbl address: 0029da58

another base object pvtbl address: 0029da58

function address in virtual table

base::func1

base::func2

base::func3

derived object pvtbl address: 0029db20

function address in virtual table

derived::func1

base::func2

derived::func3

可以看到,同一型別不同例項的虛函式表是相同的,繼承之後,子類有了自己的虛函式表,表也有相應的更新(derived::func1, derived::func3),表中未重寫的項還保留為原值(base::func2)。

總結本文標題: c++中虛函式的實現詳解

本文位址: /ruanjian/c/174579.html

c 中的虛函式詳解

廢話少說直接上 用乙個測試來闡述虛函式 include include using namespace std 有虛函式的類 class a virtual void g private int a class b public a private int b b b b b a a a a int...

C 中虛函式 虛指標和虛表詳解

關於虛函式的背景知識 用virtual關鍵字申明的函式叫做虛函式,虛函式肯定是類的成員函式。存在虛函式的類都有乙個一維的虛函式表叫做虛表。每乙個類的物件都有乙個指向虛表開始的虛指標。虛表是和類對應的,虛表指標是和物件對應的。多型性是乙個介面多種實現,是物件導向的核心。分為編譯多型性和執行多型性。執行...

C 虛函式的詳解

5.4.2 虛函式詳解 1.虛函式的定義 虛函式就是在基類中被關鍵字virtual說明,並在派生類重新定義的函式。虛函式的作用是允許在派生類中重新定義與基類同名的函式,並且可以通過基類指標或引用來訪問基類和派生類中的同名函式。虛函式的定義是在基類中進行的,它是在基類中需要定義為虛函式的成員函式的宣告...