記得有一次在面試的時候被問到虛析構函式的作用,當時回答得不是很好,故現在想重新整理下。
先看下下面的**:
#include
<
iostream
>
using
namespace
std;
class
base
~base()
//大家關鍵是看這句
virtual
void
f();
};class
derived:
public
base
~derived()
virtual
void
f()};
intmain()
大家猜猜輸出結果如何?
以下是輸出結果:
base::constructor is called!
derived::constructor is called!
*************************************
derived::f() is called!
*************************************
base::destructor is called!
請按任意鍵繼續. . .
沒錯,也許你已經看出問題的所在了。c++明確指出,當乙個繼承類經由乙個基類的指標刪除時,而該基類包含的是乙個非虛析構函式,其結果是未定義的(實際執行時通常發生的是繼承類的獨有成分沒有被銷毀。這個後果很嚴重,會造成記憶體洩漏。
不過解決這個問題的方法也很簡單。只要你在base類的析構函式~base()前加上乙個virtual就行了。這時通過基類指標刪繼承類會得到你期望的結果。
如下是使用了虛析構函式後的輸出結果:
base::constructor is called!
derived::constructor is called!
*************************************
derived::f() is called!
*************************************
derived::destructor is called!
base::destructor is called!
請按任意鍵繼續. . .
哈哈,有意思吧。以後在通過基類指標刪繼承類時你可要注意了啊!別忘了在基類宣告乙個虛析構函式!
問題還沒有結束。我們知道,如果定義了乙個普通的純虛(pure-virtual)函式的話,這個純虛(pure-virtual)函式是可以不帶函式體的。但這並對純虛(pure-virtual)析構函式來說並不成立。如果我們在基類中將析構函式定義為pure-virtual型別,那麼我們也必須為這個函式提供乙份實現。
下面是**說明:
class
base
virtual
~base()=0
;//這裡是會出現問題的,如果這個函式確實什麼也不想做,
//那麼至少定義為virtual~base()=0{}。
virtual
void
f();};
好了,就說到這吧!虛析構函式的用法雖然簡單,但它在物件導向程式設計中卻是乙個重要的技巧。那我們以後在這方面也要多加注意了哦!
virtual析構函式
當派生類物件撤銷時,一般先呼叫派生類的析構函式,然後再呼叫基類的析構函式。include using namespace std class base class derived public base int main void 執行結果 呼叫基類base的析構函式 如果在主函式中用new運算子建...
析構函式virtual與非virtual區別
析構函式virtual與非virtual區別 作為通常的原則,如果乙個類定義了虛函式,那麼它的析構函式就應當是virtual的。因為定義了虛函式則隱含著 這個類會被繼承,並且會通過基類的指標指向子類物件,從而得到多型性。這個類可能會被繼承,並且會通過基類的指標指向子類物件 因此基類的析構函式是否為虛...
C 虛析構函式 純虛析構函式
虛析構函式 析構函式的工作方式是 最底層的派生類 most derived class 的析構函式最先被呼叫,然後呼叫每乙個基類的析構函式。因為在c 中,當乙個派生類物件通過使用乙個基類指標刪除,而這個基類有乙個非虛的析構函式,則結果是未定義的。執行時比較有代表性的後果是物件的派生部分不會被銷毀。然...