C++虛函數(shù)表實例分析
多態(tài)是C++面向?qū)ο蟪绦蛟O計的一個重要特性。以前看到虛函數(shù)覺得很神奇,為什么就能實現(xiàn)多態(tài)了呢。最初的時候曾設想,要實現(xiàn)運行時多態(tài),應該讓對象的某個部分始終指向一個固定的地址,子類繼承的時候,就修改這個地址的內(nèi)容。這樣,父類和子類都是到同一個固定地址去讀取內(nèi)容,在運行時就能表現(xiàn)不同行為。
在看了《深度探索c++對象模型》之后,發(fā)現(xiàn)思路是類似的。在對象中,有一個指針指向一張?zhí)摵瘮?shù)表,里面按照次序存放了每一個虛函數(shù),當子類繼承的時候,即到虛函數(shù)表的指定位置去修改函數(shù)地址。當我們通過父類指針來操作一個子類的時候,調(diào)用虛函數(shù),都是通過虛函數(shù)表+固定的偏移,這樣運行期多態(tài)便實現(xiàn)了。
在深度《深度》這本書中,虛函數(shù)表大多放在了對象的末端,不知道現(xiàn)在的編譯器是什么樣的,因此本文就來實際做個實驗測試一下。
實驗環(huán)境:VC2013 Express
代碼如下:
class Parent {
public:
int parent;
Parent() : parent(10) {}
virtual void a() { cout << "Parent::a()" << endl; }
virtual void b() { cout << "Parent::b()" << endl; }
virtual void c() { cout << "Parent::c()" << endl; }
};
class Child : public Parent {
public:
int child;
Child() :child(100) {}
virtual void a() { cout << "Child::a()" << endl; }
virtual void b_child() { cout << "Child::b_child()" << endl; }
virtual void c_child() { cout << "Child::c_child()" << endl; }
};
class GrandChild : public Child{
public:
int grandchild;
GrandChild() :grandchild(1000) {}
virtual void a() { cout << "GrandChild::a()" << endl; }
virtual void b_child() { cout << "GrandChild::b_child()" << endl; }
virtual void c_grandchild() { cout << "GrandChild::c_grandchild()" << endl; }
};
int main()
{
typedef void(*func)();
GrandChild grandchild;
int **vtable = (int **)&grandchild;
for (int i = 0; (func)vtable[0][i] != nullptr; i++)
{
auto pfunc = (func)vtable[0][i];
cout << " ["<<i<<"] ";
pfunc();
}
return 0;
}
結果顯示如下圖所示:

確實,虛函數(shù)表指針在對象起始處,并看到了對應項被覆蓋。
相關文章
C++普通函數(shù)指針與成員函數(shù)指針實例解析
這篇文章主要介紹了C++普通函數(shù)指針與成員函數(shù)指針,很重要的知識點,需要的朋友可以參考下2014-08-08
C++類中的常數(shù)據(jù)成員與靜態(tài)數(shù)據(jù)成員之間的區(qū)別
常數(shù)據(jù)成員是指在類中定義的不能修改其值的一些數(shù)據(jù)成員,類似于我們以前學過的常變量,雖然是變量,也有自己的地址,但是一經(jīng)賦初值,便不能再被修改2013-10-10
詳解如何將Spire.PDF for C++集成到C++程序中
Spire.PDF for C++ 是一個專業(yè)的 PDF 庫,供開發(fā)人員在任何類型的 C++ 應用程序中閱讀、創(chuàng)建、編輯和轉(zhuǎn)換 PDF 文檔,本文主要介紹了兩種不同的方式將 Spire.PDF for C++ 集成到您的 C++ 應用程序中,希望對大家有所幫助2023-11-11
C語言判斷數(shù)是否為素數(shù)與素數(shù)輸出
大家好,本篇文章主要講的是C語言判斷數(shù)是否為素數(shù)與素數(shù)輸出,感興趣的同學趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽2021-12-12
詳解C++值多態(tài)中的傳統(tǒng)多態(tài)與類型擦除
值多態(tài)是一種介于傳統(tǒng)多態(tài)與類型擦除之間的多態(tài)實現(xiàn)方式,借鑒了值語義,保留了繼承,在單繼承的適用范圍內(nèi),程序和程序員都能從中受益。這篇文章主要介紹了C++值多態(tài)中的傳統(tǒng)多態(tài)與類型擦除,需要的朋友可以參考下2020-04-04

