C 中虛析構函式的作用

2021-07-02 14:39:37 字數 2197 閱讀 7826

我們知道,用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...