一、虛函式
1.如果乙個基類希望基類中的某些成員函式在子類中實現子類的自定義版本,就可以將該成員函式定義為virtual。
2.當使用基類的指標或引用呼叫乙個虛函式時,將會發生動態繫結(在執行時根據指標或引用的動態型別來決定呼叫對應動態型別中的虛函式),動態繫結發生時,編譯器無法在編譯時確定要呼叫哪個版本的虛函式。如果使用物件來呼叫成員函式,那麼在編譯期就能確定要呼叫的成員函式,因為此時類的靜態型別和動態型別是一致的
3.智慧型指標也支援虛機制
所以,虛函式的實現基礎:一是要有類的繼承,二是基類指標或引用的動態型別和靜態型別有可能不一致
4.如果基類中的成員函式是virtual的,子類經常但不總是會重寫該成員函式,如果子類不重寫虛函式,子類會直接繼承該虛函式,在呼叫該虛函式時,也依然會發生動態繫結,只不過呼叫結果類似普通成員函式
5.如果基類中的成員函式是virtual,那麼子類繼承該基類後,對應的成員函式自動都是virtual的,可以使用virtual重新宣告,也可以不使用
示例
class base2
上述**通過通過普通指標和智慧型指標分別指向子類的物件,並通過虛機制分別呼叫不同版本的虛函式
6.如果子類要重寫基類中的虛函式,那麼,重寫的虛函式的形參列表必須和基類保持一致,返回值一般情況下也要一致。除非該虛函式返回的是該類本身的指標或引用。如果定義了乙個和基類虛函式名相同但是形參列表不同的函式,那麼這兩個函式沒有任何關係,子類也沒有重寫基類中的虛函式。在c++11中,可以在子類中的虛成員函式的形參列表後使用override關鍵字來表明該成員函式是子類的自定義版本,此時,子類必須重寫父類的虛函式,此時如果形參列表不同,編譯器將報錯
示例
class base2
因為沒有加override,所以基類和子類中的虛函式即使同名,引數列表也可以不同,只不過子類沒有重寫父類的虛函式而已,兩個類中的vfunc2沒有任何關係
但是,如果給子類的vfunc2函式新增關鍵字override,則會報錯,因為此時此類必須重寫父類的虛函式,但是此時形參列表不同
可見,即使子類中虛函式的預設實參是4.4,列印出來的預設實參值依舊是基類中的預設實參值
當虛函式使用預設實參,即使基類和子類的預設實參保持一致,也無法保證基類的預設實參不變,一旦基類的預設實參發生變化,所有的子類也要跟著修改預設實參,比較麻煩,所以,當基類中的虛函式使用預設實參時,子類中的虛函式不要重新指定該預設實參
如果將基類中的vfunc2加上final關鍵字,那麼子類將不能對final進行重寫
如果乙個子類的虛函式需要呼叫基類中的對應的函式,此時如果不使用作用域運算子迴避虛機制,將導致無限遞迴
第17行因為虛機制會不停的呼叫子類中的vfunc2,導致無限遞迴,修改方法就是將動態呼叫改為靜態呼叫
參考《c++ primer》
C 知識點51 虛函式與純虛函式(下)
10.練習 示例class base 上面乙個有三個類base,derive,derive2,基類base中只定義了虛函式vfunc,base的子類derive中,定義了vfunc和vfunc2,但是vfunc和基類中的vfunc的形參列表不同,且子類中的vfunc沒有override關鍵字修飾,所...
純虛函式 虛函式 普通成員函式的知識點
1 如果乙個類的成員至少有乙個是純虛函式,那麼這個類就是純虛類。2 試圖例項化乙個抽象類物件 即包括乙個或多個純虛函式的類 是一種語法錯誤。3 如果乙個類的成員全部都是純虛函式,那麼這個類就是純虛類。4 純虛函式是用來表示介面的。5 如果乙個類的成員全部都是純虛函式,那麼這個類就是抽象類,也即介面。...
C 虛函式與純虛函式
純虛函式定義如下 virtual functionname parameter 0 類的乙個成員定位虛函式的實際意義在於讓c 知道該函式並無意義,它的作用只是為了讓派生類進行函式過載保留位置。純虛函式的定義方法就是在類的虛函式後面加上 0 標記,類中一旦出現了純虛函式的定義,那麼此類為抽象類。例項 ...