C++淺析虛函數(shù)使用方法
闡述虛函數(shù)作用和原理、純虛函數(shù)和虛函數(shù)的區(qū)別。
一、虛函數(shù)
首先來看下面這一段代碼,首先創(chuàng)建兩個類,一個是Dog,另一個是Cat,他們有一個共同的屬性:Run。在定義中每個動物都需要創(chuàng)建一個類,比較繁瑣,所以在下面的例子中,我們可以把他們簡化。
#include <iostream> using namespace std; class Dog{ public: void Run(){ cout<<"Dog->Run"<<endl; } }; class Cat{ public: void Run(){ cout<<"Cat->Run"<<endl; } }; int main() { Dog d; d.Run(); Cat c; c.Run(); return 0; }
這里使用多態(tài)和虛函數(shù),而Animal提供統(tǒng)一的接口,供子類使用,雖然代碼繁瑣,但提高了整個工程的可擴展性和靈活性。
在普通函數(shù)前加上關(guān)鍵字 virtual 構(gòu)成虛函數(shù),子類需要重寫父類的虛函數(shù),這樣在調(diào)用的時候,會覆蓋掉父類的虛函數(shù) Run,去執(zhí)行子類的Run。
#include <iostream> using namespace std; class Animal{ public: virtual void Run(){ cout<<"Animal->Run"<<endl; } }; class Dog :public Animal{ public: void Run(){ cout<<"Dog->Run"<<endl; } }; class Cat:public Animal{ public: void Run(){ cout<<"Cat->Run"<<endl; } }; int main() { Animal *ani; ani = new Dog; ani->Run(); delete ani; ani = new Cat; ani->Run(); delete ani; return 0; }
結(jié)果如下:
所以在這里只需要修改ani的指向就可以實現(xiàn)不同方法。如果不存在虛函數(shù),把Animal類的關(guān)鍵詞virtual去掉會怎么樣呢,顯然,他們會默認(rèn)實現(xiàn)父類Run的方法。
class Animal{ public: void Run(){ cout<<"Animal->Run"<<endl; } };
所以引入虛函數(shù)是為了實現(xiàn)動態(tài)多態(tài),指向不同的子類來實現(xiàn)不同的方法。
二、虛函數(shù)與純虛函數(shù)的區(qū)別
因為父類的函數(shù)可以不做任何操作,所以這里可以直接等于0;實現(xiàn)純虛函數(shù)。
//虛函數(shù) class Animal{ public: virtual void Run(){ cout<<"Animal->Run"<<endl; } };
//純虛函數(shù) class Animal{ public: virtual void Run()=0; };
虛函數(shù)與純虛函數(shù)的區(qū)別:
純虛函數(shù)只是一個接口,只能供子類去重寫實現(xiàn)方法。而虛函數(shù)在里面也可以去實現(xiàn)父類的功能。只需要指向父類的方法即可。
總結(jié):虛函數(shù)在子類里面也可以不進行重寫,但純虛函數(shù)必須在子類去實現(xiàn),如果把子類中的Run方法去掉,只留下父類中的純虛函數(shù),那么編譯器會報錯,這里大家可以試試。
三、動態(tài)多態(tài)
Animal內(nèi)部的結(jié)構(gòu)是什么樣呢?這里有一個虛函數(shù)指針(vfptr)和虛函數(shù)表(vftable)。 指針(vfptr)指向虛函數(shù)表,在虛函數(shù)表(vftable)內(nèi)記錄著虛函數(shù)的地址,即Run函數(shù)的地址。
當(dāng)子類的Dog去繼承父類后,父類的虛函數(shù)表相應(yīng)的也繼承下來,子類也會保存一份和父類相同的。
注意!這時候如果發(fā)生重寫,即子類重寫了父類的虛函數(shù),則子類的虛函數(shù)表會覆蓋父類繼承下來的虛函數(shù)表。但父類的虛函數(shù)表不會發(fā)生改變。
當(dāng)父類的指針或者引用指向子類的對象時,就發(fā)生了多態(tài)。
下面的代碼中是指向了Dog,所以會去Dog的虛函數(shù)表中找到相應(yīng)的函數(shù),在運行階段發(fā)生了動態(tài)多態(tài)。
Animal *ani; ani = new Dog; ani->Run();
到此這篇關(guān)于C++淺析虛函數(shù)使用方法的文章就介紹到這了,更多相關(guān)C++虛函數(shù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++實現(xiàn)LeetCode(9.驗證回文數(shù)字)
這篇文章主要介紹了C++實現(xiàn)LeetCode(9.驗證回文數(shù)字),本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下2021-07-07C語言文件操作實現(xiàn)數(shù)據(jù)持久化(幫你快速了解文件操作函數(shù))
持久數(shù)據(jù)其實就是將數(shù)據(jù)保存到數(shù)據(jù)庫,下面這篇文章主要給大家介紹了關(guān)于C語言文件操作實現(xiàn)數(shù)據(jù)持久化(幫你快速了解文件操作函數(shù))的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下2022-11-11如何使用C語言實現(xiàn)平衡二叉樹數(shù)據(jù)結(jié)構(gòu)算法
對于判斷是否為平衡二叉樹而言,我們需要知道以下特性:是一個二叉樹也是一個二叉排序樹該樹的每個結(jié)點上的(深度)左子樹 - 右子樹的值為平衡因子(BF(Balance Factor))該樹的每一個節(jié)點的左子樹和右子樹的高度至多等于1(平衡因子只可能是-1,0,1)2021-08-08C++類和對象之類的6個默認(rèn)成員函數(shù)詳解
類是對某一事物的抽象描述,具體地講類是C++中的一種構(gòu)造的數(shù)據(jù)類型,下面這篇文章主要給大家介紹了關(guān)于C++類和對象之類的6個默認(rèn)成員函數(shù)的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下2023-02-02OpenCV+Qt實現(xiàn)圖像處理操作工具的示例代碼
這篇文章主要介紹了利用OpenCV+Qt實現(xiàn)圖像處理操作工具,可以實現(xiàn)雪花屏、高斯模糊、中值濾波、毛玻璃等操作,感興趣的可以了解一下2022-08-08