c++本身沒有gc機制,所以需要開發人員做好記憶體管理。一般情況,c++記憶體洩露主要原因為:
1. 在構造和析構函式中,沒有匹配new和delete;
2. 沒有將基類的析構函式定義為virtual(如果沒有定義virtual的話,析構函式只清理自己的成員)
下面根據三個場景來說明基類中virtual虛析構函式的作用
1. 派生類指標指向派生類物件
#include
using
namespace std;
class
father
virtual
~father()
};class
son:
public father
~son()
};intmain
(int argc,
char
** argv)
當派生類指標指向派生類的時候,執行結果如下:
釋放指標obj的時候,呼叫順序:基類建構函式 -> 派生類建構函式 -> 派生類析構函式 -> 基類析構函式。
2.基類指標指向派生類(基類用virtual,虛析構函式)
#include
using
namespace std;
class
father
virtual
~father()
};class
son:
public father
~son()
};intmain
(int argc,
char
** argv)
用virtual析構函式的基類指向派生類,執行結果如下(與派生類指向派生類相同):
釋放指標obj的時候,呼叫順序:基類建構函式 -> 派生類建構函式 -> 派生類析構函式 -> 基類析構函式。
3.基類指標指向派生類(無virtual)
#include
using
namespace std;
class
father
~father()
};class
son:
public father
~son()
};intmain
(int argc,
char
** argv)
基類的析構函式沒有virtual,用基類指標指向派生類的時候,執行結果如下:
釋放指標obj的時候,呼叫順序:基類建構函式 -> 派生類建構函式 -> 基類析構函式。
這種情況只釋放了基類的資源,沒有呼叫派生類的析構函式,對obj進行delete的時候,派生類的資源沒有被刪除,造成記憶體洩露。
將乙個基類指標指向派生類物件,如果基類的析構函式沒有定義成virtual虛函式,編譯器的靜態繫結,在刪除基類指標的時候,只會呼叫基類的析構函式,也就意味著只釋放了基類的資源,派生類的成員沒有被釋放,因此導致記憶體沒有被完全釋放,即記憶體洩漏。
為了防止此類記憶體洩露,需要將基類的析構函式定義為virtual,從而可以在刪除基類指標的時候,一併釋放派生類的成員。
基類虛析構函式
why虛析構函式?主要還是由於基類指標或引用可以不進行顯示型別轉換的情況下指向派生類物件。同時通過引用或者指標或引用呼叫方法時遵循 例如 定義了基類brass,派生類brassplus 如果viewacct 不是虛方法,則b1 ref.viewacct 和b2 ref.viewacct 均是使用br...
基類虛析構函式分析
多型是由虛函式表來實現,通過父類指標來實現動態繫結。子類重寫父類的虛函式後,覆蓋虛函式表中父類該虛函式在表中原來的位置,也許 覆蓋 也就是由此得稱。那析構函式是否也如此呢?程式 中經常可以見到將基類的析構函式寫成虛函式,目的就是為了防止由以下這種情況造成的記憶體洩漏 class a class b ...
多型基類與虛析構函式
假設我們有乙個基類a,很不幸的,a的析構函式是乙個non virtual。同時我們有乙個派生類b,它派生自a。我們定義了乙個a型別指標,它指向的實際物件是b a ptr new b 然後在程式的某處,我們不再需要b了,我們將指標ptr delete掉 delete ptr 注意new永遠要和dele...