動態聯編是指在執行時才將函式實現和函式呼叫關聯,因此也叫執行時繫結或者晚繫結。對函式的選擇不是基於指標(引用),而是基於物件型別,不同的物件型別將做出不同的編譯結果。c++中一般情況下聯編也是靜態聯編,但是一旦涉及到多型和虛函式就必須要使用動態聯編了。
假設我們什麼都不知道,基類、派生類,虛函式、非虛函式,組合起來一共有4種:
基類(虛)、派生類(虛)√覆蓋基類(虛)、派生類(非虛)√覆蓋基類(非虛)、派生類(虛)×基類(非虛)、派生類(非虛)√ 隱藏隱藏:父類中和子類中同名的成員被隱藏。
覆蓋:子類中重寫父類的相同(同返回值,同名,同引數列表)的虛成員方法。
值得注意的是:基類實現為虛函式,子類的相應函式也會被放入vtable中,是否加上virtual關鍵字修飾就變得無關緊要。1、2說的是乙個意思。4說的是隱藏。單獨將3拿出來討論為什麼是錯的:如果基類無虛函式,派生類有虛函式,基類指標指向子類物件,記憶體布局是這樣的——
基類指標指向子類物件,無法呼叫子類的虛函式此時還不是痛點,可能就故意這麼的設計;更要命的是,如果派生類物件位於堆上,一旦以基類指標的方式delete派生類,程式將崩潰:因為基類指標指向2號位置而不是1號。
示例**說明:基類以virtual關鍵字修飾show()函式,base::show()就會被放入vtable中;派生類繼承基類,也會繼承vtable,但是派生類也有derive::show(),會發生覆蓋。**執行時,最終呼叫的是派生類的成員方法。
析構函式(destructor) 與建構函式相反,當物件結束其生命週期,如物件所在的函式已呼叫完畢時,系統自動執行析構函式。析構函式往往用來做「清理善後」 的工作(例如在建立物件時用new開闢了一片記憶體空間,delete會自動呼叫析構函式後釋放記憶體)。
乙個基類指標刪除乙個派生類物件(增加了指標成員)時,應該去呼叫派生類的析構函式而不是基類的虛函式。避免記憶體洩漏。
如果不將基類寫成虛函式,那麼通過基類指標刪除派生類物件時,就會形成記憶體洩漏。
對於圖5 所示的現象,《effective c++》 條款37是這樣解釋的:絕不重新定義繼承而來的預設引數值。virtual函式是動態繫結,而預設引數值卻是靜態繫結。
牛客網_基類指標或引用呼叫虛函式發生動多型習題
牛客網_虛函式和inline關鍵字
多型和虛函式
在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...