程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> C++ virtual虛函數

C++ virtual虛函數

編輯:關於C++
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 }

  上述是以Base為基類,並且Sub派生了Base,同時復寫了兩個函數f(),m()   當在主函數main裡用Base類型的指針指向Sub類型對象,此時利用Base指針調用f()和m(),那麼這個時候問題就來了。   在默認情況下Base類的指針會調用當前類型的方法,也就是Base::f(),Base::m(),那麼應該輸出的都是Base方法中的語句   然而結果輸出的是       為什麼會產生這種原因呢?       因為父類的f()是虛函數,那麼當基類指針調用它的派生類對象時,會默認調用多態性對象的相應方法,於是就解釋了為什麼Base* base->f()調用了派生類Sub的f()的方法,       由此我們可以知道虛函數Virtual主要是為了解決多態性問題,因為一個基類方法定義後,它的派生類對象會針對此方法進行不同的覆蓋實現,即多態性,若你此時利用基類的指針來指向基類的多態性子類,那麼就需要利用virtual修飾基類方法,從而可以來調用你所需要的派生類的方法而避免了調用基類的此方法。       Virtual是C++ OO機制中很重要的一個關鍵字。在類Base中加了Virtual關鍵字的函數就是虛擬函數(例如函數print),於是在Base的派生類Derived中就可以通過重寫虛擬函數來實現對基類虛擬函數的覆蓋。當基類Base的指針point指向派生類Derived的對象時,對point的print函數的調用實際上是調用了Derived的print函數而不是Base的print函數。這是面向對象中的多態性的體現。       還有虛函數析構函數,應用在這樣一個問題:在基類為抽象類,並且基類指針指向派生類,想要刪除這個基類指針指向的內存時   先看第一種情況  
 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變成虛函數後,成功地調用了基類和派生類的析構函數,從而實現了基類指針指向內存的完全釋放。   虛析構函數工作的方式是:最底層的派生類的析構函數最先被調用,然後各個基類的析構函數被調用。       但是有一點要注意,當某個類沒有虛函數時,那麼此類不會被當作基類,此時定義虛析構函數只會增加內存開銷,因為需要開啟一個虛函數列表來儲存。    
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved