以前沒太注意基類的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 中,當乙個派生類物件通過使用乙個基類指標刪除,而這個基類有乙個非虛的析構函式,則結果是未定義的。執行時比較有代表性的後果是物件的派生部分不會被銷毀。然...