當派生類對象從內存中撤銷時一般先運行派生類的析構函數,然后再調用基類的析構函數。
如果用new運算符建立的派生類的臨時對象,對指向基類的指針指向這個臨時對象當用delete運算符撤銷對象時,系統執行的是基類的析構函數,而不是派生類的析構函數,不能徹底的“清理現場”。
解決的方法是將基類及派生類的析構函數設為虛函數,這時無論基類指針指向哪個派生類對象,系統會采用動態關聯,調用相應的析構函數對對象進行清理。
class
Point
{
public
:
Point(){};
~Point(){ std::cout <<
"Point destructor"
<< std::endl; }
private
:
};
class
Circle
:
public
Point
{
public
:
Circle(){};
~Circle(){ std::cout <<
"Circle destructor"
<< std::endl; };
private
:
};
int
_tmain
(
int
argc
,
_TCHAR
*
argv
[])
{
Point
*p =
new
Circle
;
delete
p;
getchar();
return
0;
}
程序運行結果如下:
下面將基類的析構函數改成虛析構函數
virtual ~Point(){ std::cout <<
"Point destructor"
<< std::endl; }
其它的不變,再運行:
這樣就達到我們的目的了,基類,派生類都調用了析構函數,另外需要注意的是
在基類的析構函數聲明為虛函數時,由該基類派生的析構函數也自動成為虛函數,即使派生類的析構函數與基類的析構函數名字不相同。
程序中顯示的用delete運算符刪除一個對象,而這個對象是指向派生類對象的基類指針,系統調用相應派生類的析構函數。
如果程序中的局部對象離開其作用域,系統會隱式地調用其析構函數
咱們增加一個函數並從寫main函數:
Point
*fc()
{
Circle
cl;
Point
*p =
new
Circle
;
return
p;
}
int
_tmain
(
int
argc
,
_TCHAR
*
argv
[])
{
Point
*q = fc();
delete
q;
getchar();
return
0;
}
運行結果如下:
在上例中,函數非常fc的內部定義了兩個對象:c1和p所指向的Circle類對象。對象cl在函數fc結束時執行Circle的析構函數,撤銷局部變量c1.p所指向的對象的地址通過函數返回值賦予q,q所指向的對象在執行delete時執行析構函數。
