C++多態(tài)虛析構(gòu)和純虛析構(gòu)的實(shí)現(xiàn)
虛析構(gòu)和純虛析構(gòu)
多態(tài)使用時(shí),如果子類中有屬性開辟到堆區(qū),那么父類指針在釋放時(shí)無法調(diào)用子類的析構(gòu)代碼注釋:父類指針在釋放時(shí),只會(huì)調(diào)用父類自己的析構(gòu)函數(shù),而無法調(diào)用子類的析構(gòu)函數(shù)
解決方式:將父類的析構(gòu)函數(shù)改為虛析構(gòu)或者純虛析構(gòu)
虛析構(gòu)和純虛析構(gòu)共性:
- 可以解決父類指針釋放子類對象
- 都需要有具體的函數(shù)實(shí)現(xiàn)
虛析構(gòu)和純虛析構(gòu)區(qū)區(qū)別:
如果是純虛析構(gòu),則該類屬于抽象類,無法實(shí)例化對象
為什么需要虛析構(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<<"小貓?jiān)谡f話" << endl;//解引用
}
};
void testSpeak()
{
Animal *animal = new Cat("Tom");//有參構(gòu)造函數(shù)
animal->speak();
delete animal;
}
int main()
{
testSpeak();
}結(jié)果:
沒有調(diào)用子類的構(gòu)造函數(shù)

原因:是因?yàn)槲覀冇酶割愔羔樦赶蛄俗宇悓ο?,所以釋放父類指針時(shí),并不會(huì)調(diào)用子類的析構(gòu)代碼
父類指針在析構(gòu)時(shí)候 不會(huì)調(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ù)解決父類指針在釋放子類問題時(shí),內(nèi)存存在泄露的問題

純虛析構(gòu)
純虛析構(gòu)既要聲明也需要實(shí)現(xiàn)
- 類內(nèi)聲明
- 類外定義實(shí)現(xiàn)
有了純虛析構(gòu) 之后 ,這個(gè)類也屬于抽象類,無法實(shí)例化對象
屬性開辟到了堆區(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)的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)C++多態(tài)虛析構(gòu)和純虛析構(gòu)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++與namespace有關(guān)的兩個(gè)編譯錯(cuò)誤的講解
今天小編就為大家分享一篇關(guān)于C++與namespace有關(guān)的兩個(gè)編譯錯(cuò)誤的講解,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2019-04-04
C++學(xué)習(xí)進(jìn)階篇之類大小計(jì)算和this指針
this是C++中的一個(gè)關(guān)鍵字,也是一個(gè)const指針,它指向當(dāng)前對象,通過它可以訪問當(dāng)前對象的所有成員,下面這篇文章主要給大家介紹了關(guān)于C++學(xué)習(xí)進(jìn)階篇之類大小計(jì)算和this指針的相關(guān)資料,需要的朋友可以參考下2023-04-04
深入講解C++數(shù)據(jù)類型轉(zhuǎn)換的相關(guān)函數(shù)的知識(shí)
這篇文章主要介紹了深入講解C++數(shù)據(jù)類型轉(zhuǎn)換的相關(guān)函數(shù)的知識(shí),包括類型轉(zhuǎn)換運(yùn)算符函數(shù)等內(nèi)容,需要的朋友可以參考下2015-09-09
OpenMP task construct 實(shí)現(xiàn)原理及源碼示例解析
這篇文章主要為大家介紹了OpenMP task construct 實(shí)現(xiàn)原理及源碼示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03
舉例講解C語言程序中對二叉樹數(shù)據(jù)結(jié)構(gòu)的各種遍歷方式
這篇文章主要介紹了舉例講解C語言程序中對二叉樹數(shù)據(jù)結(jié)構(gòu)的各種遍歷方式,先序中序后序二叉樹遍歷幾乎成了最老生常談的數(shù)據(jù)結(jié)構(gòu)基礎(chǔ)知識(shí),的朋友可以參考下2016-04-04

