C 中的虛析構函式

2021-10-02 20:17:02 字數 3008 閱讀 1352

以前沒太注意基類的c++的析構函式是否為虛函式的問題,今天在拷貝乙個教程的例子下來跑的時候報錯了,後面發現該例子中的析構函式都沒寫,報了乙個錯,等下再說這個錯誤。

先看看基類析構函式為虛析構函式的應用場景:

乙個基類指標指向子類,當刪除這個基類指標時,在基類的析構函式為虛函式前提下,此時會自動呼叫子類的析構函式,釋放子類所有記憶體的目的,防止記憶體洩漏。

這種基類指標指向子類的方式,在設計模式中非常常見。

我們通過例子來體會這段話:

例一:

#include

using

namespace std;

class~(

)};// 基類

class

base

;virtual

~base()

;void

dosomething()

;};// 派生類

class

derived

:public base ;~

derived()

;void

dosomething()

;private:}

;int

main()

執行結果:

do something in class

base

!delete derived

delete base

請按任意鍵繼續.

..

// 基類

class

base;~

base()

;void

dosomething()

;};

其餘**不變,執行結果:

do something in class

base

!delete base

請按任意鍵繼續.

..

#include

using

namespace std;

class~(

)};// 基類

class

base

;virtual

~base()

;void

dosomething()

;};// 派生類

class

derived

:public base

;//~derived() ;

void

dosomething()

;private:}

;int

main()

執行結果:

do something in class

base

!delete base

請按任意鍵繼續.

..

編譯器自動幫我們新增了子類的虛構函式,而且是虛析構函式(為什麼?因為基類的析構函式是virtual,子類的析構函式自然就是虛析構函式了)

這次記憶體也沒洩漏,一切執行正常。

等等,還有一種情況呢,就是子類的指標指向子類,這時候就不用懷疑了,但是為了驗證,我們還是測試一下。

例四:

#include

using

namespace std;

class~(

)};// 基類

class

base

;virtual

~base()

;void

dosomething()

;};// 派生類

class

derived

:public base ;~

derived()

;void

dosomething()

;private:}

;int

main()

執行結果:

do something in derived

delete derived

delete base

請按任意鍵繼續.

..

例五:(在例四基礎上修改)

int

main()

system

("pause");

return0;

}

執行結果:

do something in derived

delete derived

delete base

請按任意鍵繼續.

..

例四和例五就是我們常用的,子類呼叫子類的析構函式,子類析構過程是:先呼叫基類的析構函式,再執行子類析構函式。這時候也不會有記憶體洩漏。

小計一下:

1.在基類中析構函式建議加上virtual關鍵字,使之成為虛析構函式,這樣在基類指標指向子類時,刪除該基類指標才能呼叫子類析構函式,不造成記憶體洩漏。

2.當某個類沒有子類時,析構函式當然可以不用虛析構函式了。

另外虛函式的寫法是基類中加virtual,就像例一種的virtual ~base();一樣,子類中的析構函式不用加,這是虛函式的一種通常寫法。

另外c++11中起,子類的重寫基類的虛函式最好加上override,否則編譯器會有警告。

就像下面這樣:

class

base

;virtual

~base()

;void

dosomething()

;};// 派生類

class

derived

:public base ;~

derived

() override

;void

dosomething()

;private:}

;

參考:

C 析構函式 虛析構函式

1.為什麼要定義虛析構函式?如果有乙個帶有虛函式功能的類,則它需要乙個虛析構函式,原因如下 1 如果乙個類有虛函式功能,它經常作為乙個基類使用 2 如果它是乙個基類,它的派生類經常使用new來分配 3 如果乙個派生類物件使用new來分配,並且通過乙個指向它的基類的指標來控制,那麼它經常通過乙個指向它...

C 虛析構函式 純虛析構函式

虛析構函式 析構函式的工作方式是 最底層的派生類 most derived class 的析構函式最先被呼叫,然後呼叫每乙個基類的析構函式。因為在c 中,當乙個派生類物件通過使用乙個基類指標刪除,而這個基類有乙個非虛的析構函式,則結果是未定義的。執行時比較有代表性的後果是物件的派生部分不會被銷毀。然...

C 虛析構函式 純虛析構函式

虛析構函式 析構函式的工作方式是 最底層的派生類 most derived class 的析構函式最先被呼叫,然後呼叫每乙個基類的析構函式。因為在c 中,當乙個派生類物件通過使用乙個基類指標刪除,而這個基類有乙個非虛的析構函式,則結果是未定義的。執行時比較有代表性的後果是物件的派生部分不會被銷毀。然...