虛函數的動態綁定

直接看這段代碼

 

  1. class CBase  
  2. {  
  3. public:  
  4.     virtual int func(int num=1) const    //虛函數  
  5.     {  
  6.         cout<<"CBase function! "<<num<<endl;  
  7.         return 0;  
  8.     }  
  9.     int fun2()  
  10.     {  
  11.         cout<<"CBase function2! "<<endl;  
  12.         return 0;  
  13.     }  
  14. };  
  15. class CDerive : public CBase  
  16. {  
  17. public:  
  18.     int func(int num=2) const        //在派生類中重新定義虛函數  
  19.     {  
  20.         cout<<"CDerive function! "<<num<<endl;  
  21.         return 0;  
  22.     }  
  23.     int fun2()  
  24.     {  
  25.         cout<<"CDerive function2! "<<endl;  
  26.         return 0;  
  27.     }  
  28. };  
  29.   
  30. int main()  
  31. {  
  32.     CDerive* obj1=new CDerive;  
  33.     CBase* p1=obj1;  
  34.     p1->func();  
  35.     obj1->func();  
  36.     p1->fun2();  
  37.     obj1->fun2();  
  38.     delete obj1;  
  39.     return 0;  
  40. }  



 

代碼執行的結果爲:

CDerive function! 1
CDerive function! 2
CBase function2!
CDerive function2!
Press any key to continue

 

 

都明白了不?

不明白先看點背景知識。

 

靜態多態性:函數多態性——函數重載
                           模板多態性——C++模板(類模板、函數模板)
 動態多態性:虛函數(只有用地址才能實現動態多態性)
                         
只有採用“指針->函數()”或“引用變量.函數()”的方式調用C++類中的虛函數纔會執行動態綁定。對於C++中的非虛函數,因爲其不具備動態綁定的特徵,所以不管採用什麼樣的方式調用,都不會執行動態綁定。
               
     C++語言成員函數的調用和綁定方式總結
         
代碼形式                                   對於虛函數                                                    對於非虛函數
                               作用                                  綁定方式                   作用                     綁定方式
類名::函數()        調用指定類的指定函數                 靜態綁定     調用指定類的指定函數            靜態綁定 
對象名.函數()      調用指定對象的指定函數              靜態綁定     調用指定對象的指定函數          靜態綁定 
引用變量.函數()   調用被引用對象所屬類的指定函數  動態綁定    調用引用變量所屬類的指定函數 靜態綁定 
指針->函數()      調用被引用對象所屬類的指定函數    動態綁定   調用指針變量所屬類的指定函數   靜態綁定

 

 


                             
注:被引用對象所屬類 是 指針 或 引用 指向的對象的實際類型;
    引用變量所屬類、指針變量所屬類 是 定義 引用變量、指針變量的類型;
    以上兩種類型可能相同,也可能不同。
                         
    從上表可以看出,執行動態綁定的只有通過地址,即只有通過指針或引用變量才能實現,而且還必須是虛函數。從概念上來說,虛函數機制只有在應用於地址時纔有效,因爲地址在編譯階段提供的類型信息不完全。

 

 

先看第一條:

CDerive function! 1

由p1->func();調用的虛函數,雖然p1爲基類指針,但是調用到的函數卻應該是引用對象所屬類的指定函數,也就是子類的虛函數。

CDerive* obj1=new CDerive;已經決定了p1能調用到的是子類虛函數,這就是動態綁定。

但是再看看後面的參數1,子類虛函數int func(int num=2) const  參數應該是2,這個我還不能很好的解釋。(*-*,跟飛雪溝通溝通再補充。。)

因爲,參數是在編譯時綁定,所以p1->func();的缺省參數還是基類函數的參數,沒有跟上動態綁定。只能這樣說了,反正飛雪說多了,我也搞不清。

 

第2條:

CDerive function! 2

這是我們需要的結果,不用解釋了吧

 

第3條:

CBase function2!

靜態綁定,根據指針類型調用。

第4條同3

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章