c++ map 析构函数_C++|类继承关系中的虚函数、虚析构函数、虚基类
在繼承關(guān)系中,虛函數(shù)、虛析構(gòu)函數(shù)、虛基類(lèi)中使用的關(guān)鍵字virtual都是在告訴編譯器,此處要進(jìn)行特殊處理:
虛函數(shù):函數(shù)重寫(xiě)時(shí)的要求編譯器動(dòng)態(tài)綁定來(lái)實(shí)現(xiàn)多多態(tài) ;
虛析構(gòu)函數(shù):當(dāng)基類(lèi)指針指向在堆內(nèi)實(shí)現(xiàn)的派生類(lèi)的動(dòng)態(tài)對(duì)象時(shí),virtaul聲明的基類(lèi)析構(gòu)函數(shù)是告訴編譯器,還要調(diào)用派生類(lèi)的析構(gòu)函數(shù)。
虛基類(lèi):當(dāng)派生類(lèi)有多重繼承和多繼承時(shí),在繼承鏈上有兩個(gè)子類(lèi)繼承自同一基類(lèi)時(shí),此兩個(gè)子類(lèi)作為基類(lèi)再次派生出一個(gè)類(lèi),若只想保存這兩個(gè)子類(lèi)的基類(lèi)的一個(gè)實(shí)例,需用virtual來(lái)聲明繼承關(guān)系,編譯器對(duì)虛基類(lèi)只實(shí)現(xiàn)一個(gè)實(shí)例,從而避免二義性。
1 虛函數(shù)
面向?qū)ο蟮脑诶^承時(shí)要實(shí)現(xiàn)動(dòng)態(tài)多態(tài),需要用關(guān)鍵字virtual告訴編譯器,由編譯器在編譯時(shí)生成一個(gè)虛函數(shù)表,程序運(yùn)行時(shí)實(shí)現(xiàn)每個(gè)對(duì)象通過(guò)一個(gè)自動(dòng)添加的函數(shù)指針來(lái)動(dòng)態(tài)綁定一個(gè)函數(shù)去實(shí)現(xiàn)多態(tài):
#includeclass CShape{public:virtual double Area(){cout<Area()<Area()<2 虛析構(gòu)函數(shù)
在實(shí)現(xiàn)多態(tài)時(shí),如果是由基類(lèi)指針指向在堆上動(dòng)態(tài)創(chuàng)建派生對(duì)象時(shí),如果delete此虛類(lèi)指針,則基類(lèi)的析構(gòu)函數(shù)被調(diào)用,并不會(huì)調(diào)用派生類(lèi)的析構(gòu)函數(shù),如果派生類(lèi)中有在堆上動(dòng)態(tài)創(chuàng)建的數(shù)據(jù)時(shí),則會(huì)出現(xiàn)內(nèi)存泄露。C++編譯器的做法時(shí),如果基類(lèi)的析構(gòu)函數(shù)前面有用virtual修飾,編譯器會(huì)自動(dòng)去調(diào)用派生類(lèi)的析構(gòu)函數(shù)(實(shí)現(xiàn)動(dòng)態(tài)綁定,如果其它成員函數(shù)的動(dòng)態(tài)綁定一樣),做內(nèi)存釋放的工作。
如果某個(gè)類(lèi)不包含虛函數(shù),那一般是表示它將不作為一個(gè)基類(lèi)來(lái)使用。當(dāng)一個(gè)類(lèi)不準(zhǔn)備作為基類(lèi)使用時(shí),使析構(gòu)函數(shù)為虛一般是個(gè)壞主意。因?yàn)樗鼤?huì)為類(lèi)增加一個(gè)虛函數(shù)表,使得對(duì)象的體積翻倍,還有可能降低其可移植性。實(shí)際上,很多人這樣總結(jié):當(dāng)且僅當(dāng)類(lèi)里包含至少一個(gè)虛函數(shù)的時(shí)候才去聲明虛析構(gòu)函數(shù)。
虛析構(gòu)函數(shù)是為了解決這樣的一個(gè)問(wèn)題:基類(lèi)的指針指向派生類(lèi)對(duì)象,并動(dòng)態(tài)調(diào)用派生類(lèi)的析構(gòu)函數(shù)。
#include using namespace std;class CSon{public:~CSon(){cout<3 虛基類(lèi)
當(dāng)在多條繼承路徑上有一個(gè)公共的基類(lèi),在這些路徑中的某幾條匯合處,這個(gè)公共的基類(lèi)就會(huì)產(chǎn)生多個(gè)實(shí)例(或多個(gè)副本),若只想保存這個(gè)基類(lèi)的一個(gè)實(shí)例,可以將這個(gè)公共基類(lèi)說(shuō)明為虛基類(lèi)。
如果將這種多繼承和多重繼承畫(huà)成圖形關(guān)系,會(huì)有菱形的圖案出現(xiàn),稱(chēng)為菱形繼承:
如圖,子類(lèi)D最后會(huì)接受分別來(lái)自B和C的同一個(gè)或多個(gè)相同拷貝,從而產(chǎn)生了多個(gè)拷貝,即不止一次的通過(guò)多個(gè)路徑繼承類(lèi)在內(nèi)存中創(chuàng)建了基類(lèi)成員的多份拷貝。而這些是B和C從父類(lèi)繼承而來(lái),所以D類(lèi)該繼承B還是C傳下來(lái)的,還是都接受呢?這樣就產(chǎn)生歧義(二義性),虛基類(lèi)的基本原則是在內(nèi)存中只有基類(lèi)成員的一份拷貝。這樣,通過(guò)把基類(lèi)繼承聲明為虛擬的(virtual限定符),就只能繼承基類(lèi)的一份拷貝,從而消除歧義。
#includeclass base { protected: int a; public: base(){ cout <輸出結(jié)果為:0123,如果省略掉其中的關(guān)鍵字virtual,則輸出01023,可以看出,構(gòu)造函數(shù)有重復(fù)調(diào)用。
-End-
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的c++ map 析构函数_C++|类继承关系中的虚函数、虚析构函数、虚基类的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 广州一宝马SUV冲撞人群 官方通报:已致
- 下一篇: python 多个列表合并_Python