C++虛函數(shù)表實(shí)例分析
多態(tài)是C++面向?qū)ο蟪绦蛟O(shè)計(jì)的一個(gè)重要特性。以前看到虛函數(shù)覺(jué)得很神奇,為什么就能實(shí)現(xiàn)多態(tài)了呢。最初的時(shí)候曾設(shè)想,要實(shí)現(xiàn)運(yùn)行時(shí)多態(tài),應(yīng)該讓對(duì)象的某個(gè)部分始終指向一個(gè)固定的地址,子類(lèi)繼承的時(shí)候,就修改這個(gè)地址的內(nèi)容。這樣,父類(lèi)和子類(lèi)都是到同一個(gè)固定地址去讀取內(nèi)容,在運(yùn)行時(shí)就能表現(xiàn)不同行為。
在看了《深度探索c++對(duì)象模型》之后,發(fā)現(xiàn)思路是類(lèi)似的。在對(duì)象中,有一個(gè)指針指向一張?zhí)摵瘮?shù)表,里面按照次序存放了每一個(gè)虛函數(shù),當(dāng)子類(lèi)繼承的時(shí)候,即到虛函數(shù)表的指定位置去修改函數(shù)地址。當(dāng)我們通過(guò)父類(lèi)指針來(lái)操作一個(gè)子類(lèi)的時(shí)候,調(diào)用虛函數(shù),都是通過(guò)虛函數(shù)表+固定的偏移,這樣運(yùn)行期多態(tài)便實(shí)現(xiàn)了。
在深度《深度》這本書(shū)中,虛函數(shù)表大多放在了對(duì)象的末端,不知道現(xiàn)在的編譯器是什么樣的,因此本文就來(lái)實(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)文章
一文學(xué)會(huì)c語(yǔ)言結(jié)構(gòu)體的定義和使用方法
數(shù)組是一種數(shù)據(jù)形式,其特點(diǎn)是多個(gè)相同類(lèi)型的元素集合起來(lái),結(jié)構(gòu)體是另一種重要的數(shù)據(jù)形式,特點(diǎn)是將不同類(lèi)型的成員組合起來(lái),下面這篇文章主要給大家介紹了關(guān)于c語(yǔ)言結(jié)構(gòu)體的定義和使用方法的相關(guān)資料,需要的朋友可以參考下2022-11-11C++實(shí)現(xiàn)順序排序算法簡(jiǎn)單示例代碼
這篇文章主要介紹了C++實(shí)現(xiàn)順序排序算法簡(jiǎn)單示例代碼,對(duì)于學(xué)過(guò)C++的朋友一定不會(huì)陌生,現(xiàn)在重溫一下這個(gè)算法,需要的朋友可以參考下2014-08-08c++如何將一個(gè)char轉(zhuǎn)化為string
這篇文章主要介紹了c++如何將一個(gè)char轉(zhuǎn)化為string問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-08-08C++ API功能設(shè)計(jì)的實(shí)現(xiàn)
C++ API中看似很小的修改,都可能會(huì)影響到生成的對(duì)象和庫(kù)文件的二進(jìn)制表示,如果客戶想替換共享庫(kù)使之工作,就不能簡(jiǎn)單的替換庫(kù)文件了事,而往往需要重新編譯2022-08-08C語(yǔ)言實(shí)現(xiàn)三角函數(shù)表
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言三角函數(shù)表,打印出相對(duì)應(yīng)的三角函數(shù)值,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-06-06WM_CLOSE、WM_DESTROY、WM_QUIT及各種消息投遞函數(shù)詳解
這篇文章主要介紹了WM_CLOSE、WM_DESTROY、WM_QUIT及各種消息投遞函數(shù),有助于讀者更好的理解windows程序的消息機(jī)制,需要的朋友可以參考下2014-07-07