C++?多態(tài)虛函數(shù)的底層原理深入理解
1 多態(tài)的基本概念
1.1 什么是多態(tài)?
- 多態(tài)是在不同繼承關(guān)系的類對象,去調(diào)用同一函數(shù),產(chǎn)生了不同的行為,通常是父類調(diào)用子類的重寫函數(shù),在C++中就是 父類指針指向子類對象,此時父類指針的向下引用就可以實現(xiàn)多態(tài)
比如看下面的代碼:
class Animal { public: //虛函數(shù) virtual void speak() { cout << "動物在說話" << endl; } virtual void eat(int a ) { cout << "動物在吃飯" << endl; } }; class Cat :public Animal { public: void speak() { cout << "小貓在說話" << endl; } void eat(int a) { cout << "小貓在吃飯" << endl; } }; class Dog :public Animal { public: void speak() { cout << "小狗在說話" << endl; } };
這兩個類實現(xiàn)集成關(guān)系,簡單來說就是 Animal是父類,Cat是子類,通過父類引用調(diào)用子類函數(shù),這就是多態(tài)(字面意思就是一個對象多個狀態(tài)),這樣就 符合** 高內(nèi)聚低耦合** 的設(shè)計原則,更容易 后期維護(hù)與修改
1.2 怎么實現(xiàn)多態(tài)
說了這么多,那么多態(tài)到底怎么實現(xiàn)呢?
- 想必上面代碼中也已經(jīng)透露出了一些信息,并且十分關(guān)鍵。沒錯,就是virtual,字面意思是 虛擬的,而也的確如此,這個關(guān)鍵字修飾的 函數(shù),叫做虛函數(shù),擁有虛函數(shù)的 類,被稱為 抽象類(虛類),virtual是實現(xiàn)多態(tài)的必要不充分條件
- 同時 ,子類要重寫父類的虛函數(shù),什么叫重寫?就是函數(shù)類型,函數(shù)名,參數(shù)列表完全相同。
- 并且父類指針還要指向子類對象,
正如下所示:
void doSpeak(Animal & animal) //Animal & animal = cat; { animal.speak(); } void test01() { Cat cat; doSpeak(cat); Dog dog; doSpeak(dog); }
如此方能滿足實現(xiàn)多態(tài)的三個條件:
- 注:如果沒有多態(tài),那么父類指向子類時就無法調(diào)用子類函數(shù),也就是此時該函數(shù)地址早就綁定好了,只能是animal說話,屬于靜態(tài)聯(lián)編(靜態(tài));如果想調(diào)用小貓說話,這個時候函數(shù)的地址就不能早就綁定好,而是在運(yùn)行階段再去綁定函數(shù)地址,屬于地址晚綁定,叫動態(tài)聯(lián)編,(動態(tài))多態(tài)的實現(xiàn)就是依靠動態(tài)聯(lián)編。
2 虛函數(shù)的底層原理
那么虛函數(shù)到底是怎么工作的呢?
void test02() { Animal * animal = new Cat; ((void(*)()) (*(int *)*(int *)animal)) (); typedef void( __stdcall *FUNPOINT)(int); (FUNPOINT (*((int*)*(int*)animal + 1)))(10); }
Animal * animal = new Cat;
就是animal->speak();
((void(*)()) (*(int *)*(int *)animal)) ();
這里 *(int *)animal
解引用到虛函數(shù)表中,先將animal類型的指針強(qiáng)轉(zhuǎn)為int *
,然后解引用得到int類型的值放到虛函數(shù)表中,然后偏移相應(yīng)位置指向speak()
((void(*)()) (*(int *)*(int *)animal)) ();
調(diào)用貓說話,因為C/C++默認(rèn)調(diào)用慣例 __cdecl
,而用下列調(diào)用時 是__stdcall
typedef void( __stdcall *FUNPOINT)(int); (FUNPOINT (*((int*)*(int*)animal + 1)))(10);
到此這篇關(guān)于C++ 多態(tài)虛函數(shù)的底層原理深入理解的文章就介紹到這了,更多相關(guān)C++ 多態(tài)虛函數(shù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
關(guān)于C++出現(xiàn)Bus error問題的排查與解決
項目代碼中經(jīng)常出現(xiàn)莫名其妙的Bus error問題,并且代碼中增加很多try catch 后依然不能將錯誤捕獲,一旦Bus erro出現(xiàn),進(jìn)程直接崩潰掉,所以本文給大家介紹了關(guān)于C++出現(xiàn)Bus error問題的排查與解決,需要的朋友可以參考下2024-01-01C++字符數(shù)組的輸入輸出和字符串結(jié)束標(biāo)志使用講解
這篇文章主要介紹了C++字符數(shù)組的輸入輸出和符串結(jié)束標(biāo)志使用講解,是C++入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下2015-09-09使用C++ Matlab中的lp2lp函數(shù)教程詳解
本文介紹如何使用C++編寫數(shù)字濾波器設(shè)計算法,實現(xiàn)Matlab中的lp2lp函數(shù),將低通濾波器轉(zhuǎn)換為參數(shù)化的低通濾波器,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧2023-04-04