前言
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說明,並在派生類重新定義的函式。虛函式的作用是允許在派生類中重新定義與基類同名的函式,並且可以通過基類指標或引用來訪問基類和派生類中的同名函式。虛函式的定義是在基類中進行的,它是在基類中需要定義為虛函式的成員函式的宣告...