虛擬析構函數

在類層次結構中,用多態性分配對象時會出現一個問題:

如果一個對象(帶有非虛擬析構函數)被delete操作符作用於指向對象的基類指針從而顯式刪除刪除該對象,基類析構函數(與該指針類型相匹配的)仍然會被這些對象調用。不管基類指針指向哪種對象類型,不管各個類的析構函數是否相同,都會出現這個問題。

解決該問題有個簡便方法:

聲明一個虛擬的基類析構函數,這樣就可以使所有派生類析構函數變成虛擬析構函數,即使派生類的析構函數與基類析構函數的名稱不同。這樣,如果用delete操作符作用於指向派生類對象的基類指針從而顯式刪除類層次結構的對象,就會調用合適的類的析構函數。記住,派生類對象被刪除時,派生類的基類部分也會被刪除-在派生類析構函數執行之後自動執行基類的析構函數。(摘自《C++編程金典》)

#include <iostream> using std::cin; using std::cout; using std::endl; class a { public:        a(){cout << "base class construct!" << endl;};        ~a(){cout << "base class destruct!" << endl;};        //virtual ~a(){cout << "base class destruct!" << endl;};        virtual void print()=0; }; class b : public a { public:        b(){cout << "non-base class construct!" << endl;};        ~b(){cout << "non-base class destruct!" << endl;};        virtual void print(){cout << "i am i class b!" << endl;}; }; int main() {        a *p=new b;        p->print();        delete p; } /* 輸出: base class construct! non-base class construct! i am i class b! base class destruct! 如果採用虛擬析構函數將輸出: base class construct! non-base class construct! i am i class b! non-base class destruct! base class destruct! */

如果類不用new生成,而是用

b test;

a *p=&test;

效果是一樣的,而且類b的對象test生存期是在整個main函數內;

如果這樣生成類的對象

a *p=&test();

則在下面的p->print()就會出現錯誤,因爲&test()建立了一個臨時類,而該臨時類的生存期只在這句話中,也就是說在p賦值時調用類b的構造函數,賦值完成後立即調用類b的析構函數,所以當下面再應用p來操作類b的對象時就會出現錯誤(這裏的編譯器是VC 6.0,Linux下G++沒有試過)。

發佈了18 篇原創文章 · 獲贊 4 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章