您好,登錄后才能下訂單哦!
本篇內(nèi)容介紹了“C++虛函數(shù)怎么使用”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!
首先來(lái)看下面這一段代碼,首先創(chuàng)建兩個(gè)類(lèi),一個(gè)是Dog,另一個(gè)是Cat,他們有一個(gè)共同的屬性:Run。在定義中每個(gè)動(dòng)物都需要?jiǎng)?chuàng)建一個(gè)類(lèi),比較繁瑣,所以在下面的例子中,我們可以把他們簡(jiǎn)化。
#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)一的接口,供子類(lèi)使用,雖然代碼繁瑣,但提高了整個(gè)工程的可擴(kuò)展性和靈活性。
在普通函數(shù)前加上關(guān)鍵字 virtual 構(gòu)成虛函數(shù),子類(lèi)需要重寫(xiě)父類(lèi)的虛函數(shù),這樣在調(diào)用的時(shí)候,會(huì)覆蓋掉父類(lèi)的虛函數(shù) Run,去執(zhí)行子類(lèi)的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的指向就可以實(shí)現(xiàn)不同方法。如果不存在虛函數(shù),把Animal類(lèi)的關(guān)鍵詞virtual去掉會(huì)怎么樣呢,顯然,他們會(huì)默認(rèn)實(shí)現(xiàn)父類(lèi)Run的方法。
class Animal{ public: void Run(){ cout<<"Animal->Run"<<endl; } };
所以引入虛函數(shù)是為了實(shí)現(xiàn)動(dòng)態(tài)多態(tài),指向不同的子類(lèi)來(lái)實(shí)現(xiàn)不同的方法。
因?yàn)楦割?lèi)的函數(shù)可以不做任何操作,所以這里可以直接等于0;實(shí)現(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ù)只是一個(gè)接口,只能供子類(lèi)去重寫(xiě)實(shí)現(xiàn)方法。而虛函數(shù)在里面也可以去實(shí)現(xiàn)父類(lèi)的功能。只需要指向父類(lèi)的方法即可。
總結(jié):虛函數(shù)在子類(lèi)里面也可以不進(jìn)行重寫(xiě),但純虛函數(shù)必須在子類(lèi)去實(shí)現(xiàn),如果把子類(lèi)中的Run方法去掉,只留下父類(lèi)中的純虛函數(shù),那么編譯器會(huì)報(bào)錯(cuò),這里大家可以試試。
Animal內(nèi)部的結(jié)構(gòu)是什么樣呢?這里有一個(gè)虛函數(shù)指針(vfptr)和虛函數(shù)表(vftable)。 指針(vfptr)指向虛函數(shù)表,在虛函數(shù)表(vftable)內(nèi)記錄著虛函數(shù)的地址,即Run函數(shù)的地址。
當(dāng)子類(lèi)的Dog去繼承父類(lèi)后,父類(lèi)的虛函數(shù)表相應(yīng)的也繼承下來(lái),子類(lèi)也會(huì)保存一份和父類(lèi)相同的。
注意!這時(shí)候如果發(fā)生重寫(xiě),即子類(lèi)重寫(xiě)了父類(lèi)的虛函數(shù),則子類(lèi)的虛函數(shù)表會(huì)覆蓋父類(lèi)繼承下來(lái)的虛函數(shù)表。但父類(lèi)的虛函數(shù)表不會(huì)發(fā)生改變。
當(dāng)父類(lèi)的指針或者引用指向子類(lèi)的對(duì)象時(shí),就發(fā)生了多態(tài)。
下面的代碼中是指向了Dog,所以會(huì)去Dog的虛函數(shù)表中找到相應(yīng)的函數(shù),在運(yùn)行階段發(fā)生了動(dòng)態(tài)多態(tài)。
Animal *ani; ani = new Dog; ani->Run();
“C++虛函數(shù)怎么使用”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。