一、虛函式&多型基礎
虛函式重寫:當在子類中定義了乙個與父類完全相同的虛函式時,則稱子類的這個函式重寫(也叫覆蓋)了父類的這個虛函式。
上圖中,類person和類student中的虛函式buy一樣,且student繼承了person,所以,student中的buy函式重寫(覆蓋)了person中的buy。
至於多型,其形成的條件有來兩個:
使用父類的指標或引用呼叫虛函式。
子類的虛函式重寫了父類的虛函式(上述被呼叫函式)。
另外,有關虛函式和多型還有一些需要注意的知識點:
父類成員函式無virtual時無法構成多型(此時構成重定義),子類中無virtual時可以構成多型(因為子類繼承父類,預設子類也是虛函式)。
父類與子類返回型別(值)不同時,先判斷是否是協變,若不是,則呼叫時編譯無法通過。
二、協變
協變:返回值不同,但為父子關係的指標或引用。
eg:void person* buy()
void student* buy()
呼叫時:
void fun (person* p)
發生協變時,雖然兩函式的返回型別(值)不同,但可以成功執行。此時也能構成多型。
三、總結
子類重寫父類的虛函式實現多型,要求函式名、引數列表、返回值完全相同(協變除外)。
父類中定義了虛函式,在子類中該函式始終保持虛函式的特性。
只有類的成員函式才能定義為虛函式。
靜態成員函式不能定義為虛函式。(因為沒有this指標)
如果在類外定義虛函式,只能在宣告函式時加virtual,類外定義函式時不能加virtual。
建構函式不能為虛函式,雖然可以將operator=定義為虛函式,但最好不要這樣,因為容易在使用時引起混淆。
不要在建構函式與析構函式裡面呼叫虛函式,在建構函式和析構函式中,物件是不完整的,可能發生未定義的行為。
最好把父類的析構函式宣告為虛函式。
對於第8點,這裡作一下簡單說明:
eg:
假如~a()函式未加virtual,定義 a* _pa=new b; 然後 delete _pa; ,那麼因為~a()未加virtual無法構成多型,所以調析構時,釋放空間只與型別有關,此時只調~a()。(正常情況下,調子類的析構時會自動調父類的析構,這樣才能清理子類自身中父類的成分)
四、繼承體系同名成員函式的關係
多型和虛函式
在c 中,多型是通過虛函式實現的。基類如果把乙個函式宣告為虛的 virtual 就表明繼承類可以覆蓋 override 這個函式 從而表現不同的行為,呈現出多型性 對於每乙個有虛函式的類,或者覆蓋了乙個或多個基類虛函式的繼承類,可認為有乙個與之關聯的虛函式表 v table v table 表中的每...
虛函式和多型
虛函式的概念 在類的成員函式前加virtual關鍵字,這個成員函式稱為虛函式。虛函式重寫 當在子類的定義了乙個與父類完全相同的虛函式時,則稱子類的這個函式重寫 也稱覆蓋 了父類的這個虛函式。include using namespace std class person public virtual...
虛函式和多型
pragma once 普通飛機 class plane include plane.h include using namespace std void plane fly void plane land pragma once include plane.h 直公升飛機 class jet pu...