我們知道,用c++開發的時候,用來做基類的類的析構函式一般都是虛函式。可是,為什麼要這樣做呢?下面用乙個小例子來說明:
有下面的兩個類:
class
clxbase
;virtual
~clxbase() {};
virtual
void
dosomething() ;
};class
clxderived :
public
clxbase;~
clxderived() ;
void
dosomething() ;};
**clxbase
*ptest
=new
clxderived;
ptest
->
dosomething();
delete ptest;
的輸出結果是:
do something in class clxderived!
output from the destructor of class clxderived!
這個很簡單,非常好理解。
但是,如果把類clxbase析構函式前的virtual去掉,那輸出結果就是下面的樣子了:
do something in class clxderived!
也就是說,類clxderived的析構函式根本沒有被呼叫!一般情況下類的析構函式裡面都是釋放記憶體資源,而析構函式不被呼叫的話就會造成記憶體洩漏。我想所有的c++程式設計師都知道這樣的危險性。當然,如果在析構函式中做了其他工作的話,那你的所有努力也都是白費力氣。
所以,文章開頭的那個問題的答案就是--這樣做是為了當用乙個基類的指標刪除乙個派生類的物件時,派生類的析構函式會被呼叫。
當然,並不是要把所有類的析構函式都寫成虛函式。因為當類裡面有虛函式的時候,編譯器會給類新增乙個虛函式表,裡面來存放虛函式指標,這樣就會增加類的儲存空間。所以,只有當乙個類被用來作為基類的時候,才把析構函式寫成虛函式。
寫成虛的是為了在實現多型的時候不造成記憶體洩露, 比如:
class a
; };
class b : public a
; 如果你這樣:
a *pa = new b; // upcast
然後這樣:
delete pa;
這句delete, 如果你基類的析構函式不是虛的的話, 就會造成記憶體洩露, 具體表現為派生類的記憶體被釋放了而基類沒有.
我已經給你了參考資料的地方, efftive c++裡人家說的已經很好了, 我表達能力又不好, 在繼承中使用多型來建立動態物件時, 比如上面的:a *pa = new b;
由於pa是個基類的指標, 只能識別屬於基類的部分, 所以如果沒有虛析構函式的話, 那麼子類中特有的部分就不會被釋放, 造成"經典"的釋放一半, 洩露一半的記憶體洩露.
這和object slicing的原理是一樣的, 至於object slicing:
#include
#include
using namespace std;
class pet
virtual void desc()
virtual const string& getcate()
virtual ~pet(){}
private:
string category;
}; class cat : public pet
virtual void desc()
private:
string name;
}; void describe(pet p) // object slicing
int main()
所以表現在動態物件上就會造成delete不完全, 造成記憶體洩露.
我的編譯器警告級別被我調成最高, 有一次寫類多型的時候它就警告我base類中沒有虛的虛構函式, 我開始也不懂為什麼, 但既然警告了就說明一定有問題, 後來查了資料就知道了, 自己也長了見識. 一般的, 只要乙個類要作為其他類的基類, 那麼它就一定有虛函式, 只要乙個類中有虛函式, 那麼它的析構函式就一定也要是虛的, 否則就會造成我以上所說的問題, 你以後自己多看點書查查資料吧...
參考資料:effective c++ item 7: declare destructors virtual in polymorphic base classes
C 中虛析構函式作用
我們知道,用c 開發的時候,用來做基類的類的析構函式一般都是虛函式。可是,為什麼要這樣做呢?下面用乙個小例子來說明 有下面的兩個類 class clxbase virtual clxbase virtual void dosomething class clxderived public clxba...
C 中虛析構函式的作用
我們知道,用c 開發的時候,用來做基類的類的析構函式一般都是虛函式。可是,為什麼要這樣做呢?下面用乙個小例子來說明 有下面的兩個類 class clxbase virtual clxbase virtual void dosomething class clxderived public clxba...
C 中虛析構函式的作用
收藏 我們知道,用c 開發的時候,用來做基類的類的析構函式一般都是虛函式。可是,為什麼要這樣做呢?下面用乙個小例子來說明 有下面的兩個類 class clxbase virtual clxbase virtual void dosomething class clxderived public cl...