真正理解虛析構(gòu)函數(shù)

在我真正理解虛析構(gòu)函數(shù)之前,差不多每隔一個(gè)月,我都要百度一下“虛析構(gòu)函數(shù)的作用”。因?yàn)槲以趯懸粋€(gè)類時(shí),總是不能確定是否應(yīng)該將其析構(gòu)函數(shù)寫為虛函數(shù)。直到某一天,我突然地就悟了。

事實(shí)上,虛析構(gòu)函數(shù),就是析構(gòu)函數(shù),也就是析構(gòu)函數(shù)具有了虛函數(shù)的性質(zhì)。

有如下代碼:

class CBase
{
public:
    CBase() { m_pArray = new int[20]; }
    ~CBase() { delete [] m_pArray; }
private:
    int* m_pArray;
};

class CDerived : public CBase
{
public:
    CDerived() { m_pBuffer = new char[20]; }
    ~CDerived() { delete [] m_pBuffer; }
private:
    char* m_pBuffer;
};

int main()
{
    CBase* pBase = new CDerived;
    delete pBase; // pBase->~CBase()
    return 0;
}

我們知道,delete會(huì)觸發(fā)類的析構(gòu)函數(shù),一定程度上,我們可以把它當(dāng)做調(diào)用類的析構(gòu)函數(shù)。那么delete pBase就相當(dāng)于pBase->~CBase(),此時(shí)調(diào)用的是CBase::~CBase(),而CDerived::~CDerived()未被調(diào)用,這造成了m_pBuffer的內(nèi)存泄漏。

為了解決這個(gè)問題,我們可以設(shè)置CBase析構(gòu)函數(shù)虛函數(shù)。由于虛函數(shù)多態(tài)性pBase->~CBase()實(shí)際調(diào)用的就會(huì)是CDerived::~CDerived(),而CDerived::~CDerived()又會(huì)調(diào)用CBase::~CBase()。所有的析構(gòu)函數(shù)都被調(diào)用了,就不再有內(nèi)存泄漏發(fā)生了。

解決因delete基類指針導(dǎo)致的資源泄漏,這就是虛析構(gòu)函數(shù)的作用所在;而具有虛函數(shù)性質(zhì)的析構(gòu)函數(shù),這就是虛析構(gòu)函數(shù)的真相所在。

下面兩幅圖應(yīng)該可以幫助你更好地理解:


普通析構(gòu)函數(shù)與虛析構(gòu)函數(shù)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容