為什麼基類的析構函數需要聲明為virtual??
主要内容:
1、C++類繼承中的構造函數和析構函數
2、C++多态性中的靜态綁定和動态綁定
3、C++多态性中析構函數聲明為虛函數
1、C++類繼承中的構造函數和析構函數
在C++的類繼承中,
建立對象時,首先調用基類的構造函數,然後在調用下一個派生類的構造函數,依次類推;
析構對象時,其順序正好與構造相反;
具體參考文章:http://www.cnblogs.com/AndyJee/p/4575385.html
2、C++多态性中的靜态綁定和動态綁定
對象的靜态類型:對象在聲明是采用的類型,在編譯期确定;
對象的動态類型:目前對象所指的類型,在運作期決定,對象的動态類型可以更改,但靜态類型無法更改。
靜态綁定:綁定的是對象的靜态類型,某特性(比如函數)依賴于對象的靜态類型,發生在編譯期。
動态綁定:綁定的是對象的動态類型,某特性(比如函數)依賴于對象的動态類型,發生在運作期。
具體參考文章:http://www.cnblogs.com/AndyJee/p/4575670.html
3、C++多态性中基類析構函數聲明為虛函數
先來看幾段程式例子:
- 将基類析構函數聲明為虛函數
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | |
運作結果:

- 不将基類析構函數聲明為虛函數:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | |
運作結果:
可以看出:
在用基類指針指向派生類時,
在基類析構函數聲明為virtual的時候,delete基類指針,會先調用派生類的析構函數,再調用基類的析構函數。
在基類析構函數沒有聲明為virtual的時候,delete基類指針,隻會調用基類的析構函數,而不會調用派生類的析構函數,這樣會造成銷毀對象的不完全。
分析:
Person *pt2 = new Student;
pt2的靜态類型為Person,而動态類型為Student,
當析構函數為虛函數時,為動态綁定,delete pt2,會調用動态類型即派生類的析構函數,由于繼承關系,也會調用基類的析構函數;
而當析構函數為非虛函數時,為靜态綁定,delete pt2,會調用靜态類型即基類的析構函數,而不會調用派生類的析構函數。
(以上純屬個人了解)
總結:
- 應該為多态基類聲明虛析構器。一旦一個類包含虛函數,它就應該包含一個虛析構器,因為多态性,必定會有基類調用派生類。
- 如果一個類不用作基類或者不需具有多态性,便不應該為它聲明虛析構器。
轉自:
https://www.cnblogs.com/AndyJee/p/4575810.html