C 的虛析構函式的作用

2022-05-13 22:39:06 字數 1635 閱讀 2599

我們知道,用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++程式設計師都知道這樣的危險性。當然,如果在析構函式中做了其他工作的話,那你的所有努力也都是白費力氣。

所以,文章開頭的那個問題的答案就是--這樣做是為了當用乙個基類的指標刪除乙個派生類的物件時,派生類的析構函式會被呼叫。

當然,並不是要把所有類的析構函式都寫成虛函式。因為當類裡面有虛函式的時候,編譯器會給類新增乙個虛函式表,裡面來存放虛函式指標,這樣就會增加類的儲存空間。所以,只有當乙個類被用來作為基類的時候,才把析構函式寫成虛函式。

所以注意如果基類不是虛析構函式的話可能會有以下兩點問題:

1、子類所分配的記憶體不能被釋放

2、子類中成員變數類所分配的記憶體也不能被釋放,因為子類析構函式沒有被呼叫,其變數的析構函式肯定也沒被呼叫了

建構函式不能用虛擬,因為用也沒用,不管是在棧上構造物件,還是在堆上構造物件,也不管你以後是否使用父類的指標或引用來指向或引用這個物件,在構造的那「一瞬間」,總歸要指明要構造物件的具體型別,所以,物件在構造過程中不存在執行時動態繫結的多型行為。

你理解這個意思嗎?舉了例子就明白了,通常,假如a是b的父類,

a* p = new b();

則對於虛函式f,可以通過a類的指標p直接呼叫到b類的函式,這就是執行時的多型:

p->f();

但你注意沒有,b類的物件卻必須通過「a* p = new b();」來構造,顯然不能通過「a* p = new a();」來構造乙個b類物件——這是荒唐的,這只能構造乙個a類的物件。所以建構函式虛擬無意義。

但析構函式就不同了,p明明是個a類的指標,如果析構函式不是虛擬的,那麼,你後面就必須這樣才能安全的刪除這個指標:

delete (b*)p;

但如果建構函式是虛擬的,就可以在執行時動態繫結到b類的析構函式,直接:

delete p;

就可以了。這就是虛析構函式的作用。而事實上,在執行時,你並不是總是能知道p所指物件的實際型別從而進行強制轉換,所以,c++語言既然要支援多型,也就必須支援虛擬析構。

C 虛析構函式的作用

c 中經常將基類的析構函式定義為虛函式。當用基類指標去去釋放乙個派生類物件時,如果基類的析構函式沒有定義為虛函式,則不會呼叫派生類的析構函式,這樣會造成記憶體洩漏。如下例子 note your choice is c ide include stdio.h include iostream usin...

C 虛析構函式的作用

1 作用 為了在實現多型的時候不造成記憶體洩露,如果基類析構函式前不加vitual,派生類物件被銷毀後,只會呼叫基類的析構函式,而不會去呼叫派生類的析構函式。2 對於正常的函式,如果基類中宣告為virtual,則派生類可以不用再寫virtual c sharp view plain copy inc...

C 的虛析構函式的作用

我們知道,用c 開發的時候,用來做基類的類的析構函式一般都是虛函式。可是,為什麼要這樣做呢?下面用乙個小例子來說明 有下面的兩個類 class clxbase virtual clxbase virtual void dosomething class clxderived public clxba...