轉載位址:http://blog.chinaunix.net/uid-25808509-id-3026857.html
有時候我們需要用基類的指針删除其子類的對象,這時候要非常注意,倘若基類的析構函數是 non-virtual析構函數,那麼事實上,隻有基類的析構函數被調用,派生類的析構函數并沒有被調用,這可能會導緻資源洩漏。為避免這中情況發生,我們可以将基類的析構函數聲明為virtual,這樣的話,子類對象才能被完全銷毀.
#include <iostream>
#include <stdlib.h>
#include <crtdbg.h>
#ifdef _DEBUG
#define new new(_NORMAL_BLOCK, __FILE__, __LINE__)
#endif
using namespace std;
class BaseClass
{
public:
virtual ~BaseClass() = 0;
//~BaseClass();
};
BaseClass::~BaseClass()
{
cout << "the ~BaseClass is called" << endl;
}
class DerivedClass : public BaseClass
{
public:
DerivedClass(int x, int y)
:X(x)
,Y(y)
{
a = new int[y];
}
~DerivedClass()
{
cout << "the ~Derivedclass is called" << endl;
if(a)
{
delete a;
a = NULL;
}
}
private:
int X;
int Y;
int *a;
};
void main()
{
//memory check
_CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF);
BaseClass *bs= new DerivedClass(2, 3);
delete bs;
system("pause");
}
程式運作結果為
the ~Derivedclass is called
the ~BaseClass is called
基類和派生類的析構函數都被調用
倘若基類的析構函數為~BaseClass();即 non-virtual 析構函數,
程式運作結果為
the ~BaseClass is called,
隻有基類的析構函數被調用,子類中指針 a 指向的記憶體并沒有被釋放
Dumping objects ->
e:\work\test\test\test.cpp(287) : {128} normal block at 0x00395E38, 12 bytes long.
Data: < > CD CD CD CD CD CD CD CD CD CD CD CD
Object dump complete.
12 位元組的記憶體洩漏了
是以,隻有當一個類被用來作為基類的時候,才會把析構函數寫成虛函數。