本文不討論虛函數的原理,只簡單總結下虛函數的常用事項。
虛函數(虛方法)是C++動態聯編 實現多態的重要手段,在函數聲明時使用關鍵字virtual即可,如: virtual void func(void);
注意:虛函數(虛方法)只針對類的成員函數,普通函數不可聲明為虛函數!且一般只有在用到繼承時才將基類的成員函數聲明為虛函數!
請看如下代碼:
1 class parentClass 2 { 3 public: 4 parentClass(); 5 ~parentClass(); 6 7 void func_1(void); 8 virtual void func_2(void); 9 private: 10 }; 11 12 class childClass : public parentClass 13 { 14 public: 15 childClass(); 16 ~childClass(); 17 18 void func_1(void); 19 virtual void func_2(void); 20 private: 21 };
假如有以上聲明,則在使用以上類時:
1 childClass childTest; 2 parentClass *pParentTest = &childTest; 3 pParentTest->func_1(); 4 pParentTest->func_2();
pParentTest指針類型是parentClass基類類型,但它指向的地址對象卻是childClass的對象,這種情況下:func_1函數不是虛函數,則調用的是指針類型所在類的函數,即第三句執行的是基類中的func_1函數;func_2函數是虛函數,則調用的是指針指向對象的所在類的函數,即第四句執行的是子類中的func_2函數。
上面兩段代碼演示了虛函數最基本的使用,簡單總結就是:基類中將某方法定義為虛函數,則在派生類中,該方法仍為虛方法。在使用時,定義基類類型的指針,使其指向派生類的對象,使用該指針調用某個方法,若該方法未被聲明為虛函數,則調用的是指針類中的方法,若該方法是虛函數,則調用的是指針指向對象類中的該方法。這也即是動態聯編。
其他情況:
1) 如上述4行代碼,若有pParentTest->func_3();語句,其中func_3函數只在派生類中聲明,基類中沒有該方法,則會 編譯報錯 ;
2) 如上述4行代碼,若有pParentTest->func_3();語句,其中func_3函數只在基類中聲明,派生類中沒有該方法,則會 調用基類的方法 ;
3) 如果基類聲明被重載了,則應在派生類中重新定義所有的基類版本!如果派生類只重新定義了1個版本,則另外的版本將被隱藏,派生類對象無法調用;
4) 如果派生類要重新定義基類的方法,則派生類中的聲明應與基類一致(函數名、參數、返回值),如果派生類的聲明與基類參數不一致,則派生類的該方法將覆蓋基類中的該方法(不構成重載),派生類對象只能按照派生類方法聲明的格式進行調用!(基類中的該方法將被隱藏,派生類對象調用時會報錯)
虛方法的一般使用條件:
1) 需要在派生類中重新定義基類的方法,則在基類中將該方法聲明為虛方法;
2) 涉及到派生的,一般都將析構函數聲明為虛函數;
3) 構造函數不能為虛函數!
4) 友元函數不能是虛函數,因為它不是類的成員函數!