重写,重定义,重载
?》 重寫,重定義經常與繼承和虛繼承一起使用,那么我們一步一步來,先看看重寫,重定義到底是什么樣子的呢?
?》重載:
? ? ? ? ? ?1.它在同一個作用域中
? ? ? ? ? ?2.函數名必須相同
? ? ? ? ? ?3.參數個數,類型,順序不同
? ? ? ? ? ?4.返回值不作要求
? ? ? ? ? ?5.virtual關鍵字不作要求
?》重寫(覆蓋):
? ? ? ? ? ? 1.不在同一個作用域中(即基類與子類中)
? ? ? ? ? ? 2.函數名相同,返回值相同,參數也相同
? ? ? ? ? ? 3.只是在基類同名函數前必須有virtual關鍵字不能有static。
? ? ? ? 這時派生類的重寫函數就會覆蓋基類中的同名函數。
?》重定義(隱藏):
? ? ? ? ? ? ?1.不再同一個作用域(即基類與子類中)
? ? ? ? ? ? ?2.函數名相同
? ? ? ? ? ? ?3.返回值不作要求
? ? ? ? ? ? ?4. 參數相同時,基類同名函數前不能有virtual關鍵字
? ? ? ? ? ? ? ?參數不同時,基類同名函數前有無virtual關鍵字不作要求。
? ? ? ? 這時派生類的重寫函數就會隱藏基類中的同名函數。
? 在這里我引申一個新的概念叫做協變:當函數不在同一個作用域,函數名相同并且基類函數前有virtual關鍵字但是返回值返回的是基類對象的指針或者引用時就認為是協變。
舉個例子:
class?Base { public:virtual?void?f1();virtual?void?f2();void?f3();void?f4(); }; class?Deriver?:public?Base { public?:void?f1();?????//函數重寫,這里的virtual可以不寫,基類函數覆蓋void?f2(int?x);//重定義char?f3();?????//重定義void?f4();????//重定義 }; void?Base::f1() { cout?<<?"--Base-f1--"?<<?endl; } void?Base::f2() { cout?<<?"--Base-f2--"?<<?endl; } void?Base::f3() { cout?<<?"--Base-f3--"?<<?endl; } void?Base::f4() { cout?<<?"--Base-f4--"?<<?endl; } void?Deriver::f1() { cout?<<?"--Deriver-f1--"?<<?endl; } void?Deriver::f2(int?x) { cout?<<?"--Deriver-f2--"?<<?endl; } char?Deriver::f3() { cout?<<?"--Deriver-f3--"?<<?endl; } void?Deriver::f4() { cout?<<?"--Deriver-f4--"?<<?endl; } int?main() { Base?d1,?*bp; Deriver?d2; bp?=?&d2; bp->f1(); bp->f2(); bp->f4(); return?0; }結果:
? ?
1.Derived類中的函數f1()是對Base類中函數f1()的重寫,即使用了虛函數特性。
2.Derived類中的函數f2()是對Base類中函數f2()的隱藏,即重定義了。
3.因為Base類的函數f3()和f4()沒有定義為virtual虛函數,所以Derived類的函數f3()和f4()是對Base::c()的重定義。
4.bp指針是一個指向Base類型的指針,但是它實際指向了一個Derived的空間,這里對pd調用函數的處理(多態性)取決于是否重寫(虛函數特性)了函數,若沒有,則依然調用基類。
5.只有在通過基類指針或基類引用 間接指向派生類類型時多態性才會起作用。
轉載于:https://blog.51cto.com/940814wang/1765411
總結