C++虛函數(shù)表實(shí)例分析
多態(tài)是C++面向?qū)ο蟪绦蛟O(shè)計(jì)的一個(gè)重要特性。以前看到虛函數(shù)覺得很神奇,為什么就能實(shí)現(xiàn)多態(tài)了呢。最初的時(shí)候曾設(shè)想,要實(shí)現(xiàn)運(yùn)行時(shí)多態(tài),應(yīng)該讓對(duì)象的某個(gè)部分始終指向一個(gè)固定的地址,子類繼承的時(shí)候,就修改這個(gè)地址的內(nèi)容。這樣,父類和子類都是到同一個(gè)固定地址去讀取內(nèi)容,在運(yùn)行時(shí)就能表現(xiàn)不同行為。
在看了《深度探索c++對(duì)象模型》之后,發(fā)現(xiàn)思路是類似的。在對(duì)象中,有一個(gè)指針指向一張?zhí)摵瘮?shù)表,里面按照次序存放了每一個(gè)虛函數(shù),當(dāng)子類繼承的時(shí)候,即到虛函數(shù)表的指定位置去修改函數(shù)地址。當(dāng)我們通過父類指針來操作一個(gè)子類的時(shí)候,調(diào)用虛函數(shù),都是通過虛函數(shù)表+固定的偏移,這樣運(yùn)行期多態(tài)便實(shí)現(xiàn)了。
在深度《深度》這本書中,虛函數(shù)表大多放在了對(duì)象的末端,不知道現(xiàn)在的編譯器是什么樣的,因此本文就來實(shí)際做個(gè)實(shí)驗(yàn)測(cè)試一下。
實(shí)驗(yà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; }
結(jié)果顯示如下圖所示:
確實(shí),虛函數(shù)表指針在對(duì)象起始處,并看到了對(duì)應(yīng)項(xiàng)被覆蓋。
相關(guān)文章
C++普通函數(shù)指針與成員函數(shù)指針實(shí)例解析
這篇文章主要介紹了C++普通函數(shù)指針與成員函數(shù)指針,很重要的知識(shí)點(diǎn),需要的朋友可以參考下2014-08-08C/C++ 中sizeof(''a'')對(duì)比詳細(xì)介紹
這篇文章主要介紹了C/C++ 中sizeof('a')的值對(duì)比詳細(xì)介紹的相關(guān)資料,需要的朋友可以參考下2017-02-02C++類中的常數(shù)據(jù)成員與靜態(tài)數(shù)據(jù)成員之間的區(qū)別
常數(shù)據(jù)成員是指在類中定義的不能修改其值的一些數(shù)據(jù)成員,類似于我們以前學(xué)過的常變量,雖然是變量,也有自己的地址,但是一經(jīng)賦初值,便不能再被修改2013-10-10詳解如何將Spire.PDF for C++集成到C++程序中
Spire.PDF for C++ 是一個(gè)專業(yè)的 PDF 庫,供開發(fā)人員在任何類型的 C++ 應(yīng)用程序中閱讀、創(chuàng)建、編輯和轉(zhuǎn)換 PDF 文檔,本文主要介紹了兩種不同的方式將 Spire.PDF for C++ 集成到您的 C++ 應(yīng)用程序中,希望對(duì)大家有所幫助2023-11-11C語言判斷數(shù)是否為素?cái)?shù)與素?cái)?shù)輸出
大家好,本篇文章主要講的是C語言判斷數(shù)是否為素?cái)?shù)與素?cái)?shù)輸出,感興趣的同學(xué)趕快來看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽2021-12-12詳解C++值多態(tài)中的傳統(tǒng)多態(tài)與類型擦除
值多態(tài)是一種介于傳統(tǒng)多態(tài)與類型擦除之間的多態(tài)實(shí)現(xiàn)方式,借鑒了值語義,保留了繼承,在單繼承的適用范圍內(nèi),程序和程序員都能從中受益。這篇文章主要介紹了C++值多態(tài)中的傳統(tǒng)多態(tài)與類型擦除,需要的朋友可以參考下2020-04-04