1 #include<iostream> 2 using namespace std; 3 class Base{ 4 public: 5 void m() 6 { 7 cout << "it's Base's m() " << endl; 8 } 9 virtual void f() 10 { 11 cout << "it's Base's f()" << endl; 12 } 13 }; 14 class Sub: public Base 15 { 16 void m() 17 { 18 cout << "it's Sub's m()" << endl; 19 } 20 void f() 21 { 22 cout << "it's Sub's f()" << endl; 23 } 24 }; 25 void main() 26 { 27 Base* base = new Sub; 28 base->f(); 29 base->m(); 30 }
1 de<iostream> 2 using namespace std; 3 class Base{ 4 public: 5 Base() 6 { 7 } 8 ~Base() 9 { 10 cout << "Base has deleted" << endl; 11 } 12 }; 13 class Sub: public Base 14 { 15 public: 16 Sub() 17 { 18 } 19 ~Sub() 20 { 21 cout << "Sub has delete" << endl; 22 } 23 }; 24 void main() 25 { 26 Base* base = new Sub; 27 delete base; 28 base = NULL; 29 }
此時是用基類Base指針去操作繼承類Sub,在delete Base*指針後,我們可以從結果得到只調用了基類的析構函數,但是派生類的析構函數並沒有調用,這相當於內存只是刪除了一一半,還有一半內存為刪除,導致了內存洩漏,此時則需要用到虛析構函數,來達到調用派生類的析構函數來刪除內存空間的目的,也就是下面這種情況:
1 #include<iostream> 2 using namespace std; 3 class Base{ 4 public: 5 Base() 6 { 7 } 8 virtual ~Base() 9 { 10 cout << "Base has deleted" << endl; 11 } 12 }; 13 class Sub: public Base 14 { 15 public: 16 Sub() 17 { 18 } 19 ~Sub() 20 { 21 cout << "Sub has delete" << endl; 22 } 23 }; 24 void main() 25 { 26 Base* base = new Sub; 27 delete base; 28 base = NULL; 29 }
此時我們可以看到在基類析構函數加了Virtual變成虛函數後,成功地調用了基類和派生類的析構函數,從而實現了基類指針指向內存的完全釋放。 虛析構函數工作的方式是:最底層的派生類的析構函數最先被調用,然後各個基類的析構函數被調用。 但是有一點要注意,當某個類沒有虛函數時,那麼此類不會被當作基類,此時定義虛析構函數只會增加內存開銷,因為需要開啟一個虛函數列表來儲存。