基類的析構函式為什麼一般都是虛函式

2021-06-17 20:59:31 字數 1535 閱讀 8971

先引用一段話

為什麼析構函式總是虛函式?如果這是必要的,那麼為什麼c++不把虛析構函式直接作為預設值?為什麼純虛析構函式可以通過編譯,但是不能通過連線?

回答:編譯器總是根據型別來呼叫類成員函式。但是乙個派生類的指標可以安全地轉化為乙個基類的指標。這樣刪除乙個基類的指標的時候,c++不管這個指標指向乙個基類物件還是乙個派生類的物件,呼叫的都是基類的析構函式而不是派生類的。如果你依賴於派生類的析構函式的**來釋放資源,而沒有過載析構函式,那麼會有資源洩漏。

所以建議的方式是將析構函式宣告為虛函式。如果你使用mfc,並且以cobject或其派生類為基類,那麼mfc已經為你做了這件事情;cobject的析構函式是虛函式。乙個函式一旦宣告為虛函式,那麼不管你是否加上virtual 修飾符,它在所有派生類中都成為虛函式。但是由於理解明確起見,建議的方式還是加上virtual 修飾符。

c++不把虛析構函式直接作為預設值的原因是虛函式表的開銷以及和c語言的型別的相容性。有虛函式的物件總是在開始的位置包含乙個隱含的虛函式表指標成員。

如果是對於mfc類cpoint和csize這樣的小型類,增加乙個指標就增加了很多記憶體占用,而且使得其記憶體表示和基類point和size不一致。如果兩個類的記憶體表示一致,那麼這樣你可以安全地把乙個類的指標或陣列當作另乙個類的指標或陣列使用。

#ifndef __hji__panda__

#define __hji__panda__

#include #include "bear.h"

class panda : public bear

;#endif /* defined(__hji__panda__) */

#include "panda.h"

#include "bear.h"

panda::panda()

;#endif /* defined(__hji__bear__) */

#include "bear.h"

bear::bear()

;#endif /* defined(__hji__animal__) */

#include "animal.h"

animal::animal()

//執行結果
animal init...

bear init...

panda init...

panda delete...

bear delete...

animal delete...

如果把基類animal的virtual去掉,則不會構成動態繫結(基類指標呼叫虛成員函式),然後就只輸出 然後就只輸出animal的析構,反之,加上的話,就是動態繫結了,呼叫panda的析構,然後再一層層往上析構。

另外,最頂端基類animal設為virtual之後,他的派生類的析構函式也會預設為virtual,一虛到底!所以也就不用再為bear制定virtual型別了。

為什麼基類的析構函式是虛函式

1.為什麼基類的析構函式是虛函式?在實現多型時,當用基類操作派生類,在析構時防止只析構基類而不析構派生類的狀況發生。下面 網路 源位址 a.第一段 includeusing namespace std class clxbase clxbase void dosomething class clxd...

為什麼基類的析構函式是虛函式

1.為什麼基類的析構函式是虛函式?在實現多型時,當用基類操作派生類,在析構時防止只析構基類而不析構派生類的狀況發生。下面 網路 源位址 a.第一段 includeusing namespace std class clxbase clxbase void dosomething class clxd...

為什麼基類的析構函式是虛函式?

注 本文章內容大部分來自 整理 1.為什麼基類的析構函式是虛函式?在實現多型時,當用基類操作派生類,在析構時防止只析構基類而不析構派生類的狀況發生。a.第一段 include using namespace std class clxbase clxbase void dosomething cla...