C++多態(tài)虛析構(gòu)和純虛析構(gòu)的實現(xiàn)
虛析構(gòu)和純虛析構(gòu)
多態(tài)使用時,如果子類中有屬性開辟到堆區(qū),那么父類指針在釋放時無法調(diào)用子類的析構(gòu)代碼注釋:父類指針在釋放時,只會調(diào)用父類自己的析構(gòu)函數(shù),而無法調(diào)用子類的析構(gòu)函數(shù)
解決方式:將父類的析構(gòu)函數(shù)改為虛析構(gòu)或者純虛析構(gòu)
虛析構(gòu)和純虛析構(gòu)共性:
- 可以解決父類指針釋放子類對象
- 都需要有具體的函數(shù)實現(xiàn)
虛析構(gòu)和純虛析構(gòu)區(qū)區(qū)別:
如果是純虛析構(gòu),則該類屬于抽象類,無法實例化對象
為什么需要虛析構(gòu)
#include<iostream> #include<string> using namespace std; //虛析構(gòu)和純虛析構(gòu) class Animal { public: Animal() { cout << "調(diào)用了父類的構(gòu)造函數(shù)" << endl; } ~ Animal() { cout << "調(diào)用了父類的析構(gòu)函數(shù)" << endl; } virtual void speak() = 0;//純虛函數(shù) }; class Cat :public Animal { public: string *m_Name; //在子類的構(gòu)造函數(shù),加入小貓的姓名 Cat(string name) { cout << "調(diào)用了子類-小貓類的構(gòu)造函數(shù)" << endl; m_Name = new string(name);//在堆區(qū)創(chuàng)建 } ~Cat() { if (m_Name != NULL) { delete m_Name; m_Name = NULL; cout<<"調(diào)用了子類-小貓類的析構(gòu)函數(shù)"<<endl; } } virtual void speak() { cout << *m_Name<<"小貓在說話" << endl;//解引用 } }; void testSpeak() { Animal *animal = new Cat("Tom");//有參構(gòu)造函數(shù) animal->speak(); delete animal; } int main() { testSpeak(); }
結(jié)果:
沒有調(diào)用子類的構(gòu)造函數(shù)
原因:是因為我們用父類指針指向了子類對象,所以釋放父類指針時,并不會調(diào)用子類的析構(gòu)代碼
父類指針在析構(gòu)時候 不會調(diào)用子類中析構(gòu)函數(shù),導(dǎo)致子類如果有堆區(qū)屬性,出現(xiàn)內(nèi)存泄漏
解決辦法:
在父類析構(gòu)函數(shù)前加入關(guān)鍵字 virtual
//虛析構(gòu)和純虛析構(gòu) class Animal { public: Animal() { cout << "調(diào)用了父類的構(gòu)造函數(shù)" << endl; } virtual ~ Animal() { cout << "調(diào)用了父類的析構(gòu)函數(shù)" << endl; } virtual void speak() = 0;//純虛函數(shù) };
虛析構(gòu)函數(shù)用途
可以利用虛析構(gòu)函數(shù)解決父類指針在釋放子類問題時,內(nèi)存存在泄露的問題
純虛析構(gòu)
純虛析構(gòu)既要聲明也需要實現(xiàn)
- 類內(nèi)聲明
- 類外定義實現(xiàn)
有了純虛析構(gòu) 之后 ,這個類也屬于抽象類,無法實例化對象
屬性開辟到了堆區(qū)
//虛析構(gòu)和純虛析構(gòu) class Animal { public: Animal() { cout << "調(diào)用了父類的構(gòu)造函數(shù)" << endl; } //virtual ~ Animal() //{ // cout << "調(diào)用了父類的析構(gòu)函數(shù)" << endl; //} virtual ~Animal() = 0;//純虛析構(gòu) virtual void speak() = 0;//純虛函數(shù) }; Animal::~Animal() { cout << "調(diào)用了父類的純虛析構(gòu)函數(shù)" << endl; }
結(jié)果
總結(jié):
- 虛析構(gòu)或純虛析構(gòu)就是用來解決通過父類指針釋放子類對象
- 如果子類中沒有堆區(qū)數(shù)據(jù),可以不寫為虛析構(gòu)或純虛析構(gòu)
- 擁有純虛析構(gòu)函數(shù)的類也屬于抽象類
到此這篇關(guān)于C++多態(tài)虛析構(gòu)和純虛析構(gòu)的實現(xiàn)的文章就介紹到這了,更多相關(guān)C++多態(tài)虛析構(gòu)和純虛析構(gòu)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++實現(xiàn)LeetCode(145.二叉樹的后序遍歷)
這篇文章主要介紹了C++實現(xiàn)LeetCode(145.二叉樹的后序遍歷),本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07C語言 動態(tài)內(nèi)存開辟常見問題解決與分析流程
動態(tài)內(nèi)存是相對靜態(tài)內(nèi)存而言的。所謂動態(tài)和靜態(tài)就是指內(nèi)存的分配方式。動態(tài)內(nèi)存是指在堆上分配的內(nèi)存,而靜態(tài)內(nèi)存是指在棧上分配的內(nèi)存2022-03-03