(七) c 多型的實現過程

2021-08-29 12:00:01 字數 1215 閱讀 8191

當乙個類 a 中有虛函式時,a 這個類會自動生成一張虛函式表記錄該 a 類所擁有的虛函式,並用乙個指標 __vfptr 指向該錶。當 a  類被當作父類讓子類 b 繼承時,顯然子類 b 也會繼承父類 a 的虛函式表指標  __vfptr。當子類 b 修改了虛函式,那麼父類虛函式表指標 __vfptr 所指向的內容就會被子類 b 修改。具體體現為,當父類 a 虛函式表中記錄了乙個虛函式入口位址為0x11111111,在子類 b 中修改了這個虛函式,子類的這個虛函式入口位址為0x22222222, 那麼父類 a 的虛表指標當中的0x11111111

就會被修改為 0x22222222。這樣就達到了父類可以呼叫子類方法的神奇過程。當然子類新加的虛函式父類是無法呼叫的,子類會有自己的虛函式表,用於被他人繼承。

當子類繼承父類時,也會把自身新加的虛函式加入到父類的虛函式表 中,但父類無法呼叫子類新加的虛函式,其原因在於父類當中並沒有子類新加虛函式的宣告,你雖然有函式入口位址,但通過父類去呼叫時,父類並不認識這些入口位址對應的函式。

當子類繼承多個父類時,只會在繼承宣告的第乙個父類的虛表中新增子類新加的虛函式。而子類對父類虛函式的修改會對所有父類虛表生效。

// 64位系統下的測試

// 不加 virtual 關鍵字,該類大小為8,加了之後為16

#include using namespace std;

class test

private:

int data;

};int main()

首先明白一點虛函式都是針對於類來說的。在實際生活中,我們永遠無法通過不具體的動物生出新的動物物件,只有當動物具體到某一物種時才可以產生新的物件。就比如說你說動物生了乙個動物,這句話是毫無意義的,你不知道新生動物的外形,習慣等等有用資訊,但你說狗生了乙隻狗,那麼你就可以想象新生的狗的樣子,你也會知道新生的狗喜歡吃屎這個特點。          但是所有的物種都是由動物派生而來,但是我們又不能把動物的特點確定下來。為了解決這類問題,純虛函式就應運而生。

純虛函式寫法:virtual 返回值 函式名(引數列表) = 0;

測試**

#include using namespace std;

class animal

;class dog: public animal

int main(void)

C 多型的實現

封裝 繼承 多型,物件導向的三大特性,前兩項理解相對容易,但要理解多型,特別是深入的了解,對於初學者而言可能就會有一定困難了。我一直認為學習oo的最好方法就是結合實踐,封裝 繼承在實際工作中的應用隨處可見,但多型呢?也許未必,可能不經意間用到也不會把它跟 多型 這個詞對應起來。在此拋磚引玉,大家討論...

C 多型的實現

多型的繫結可以分為執行是多型和編譯時多型 編譯時的多型性 編譯時的多型性是通過過載來實現的。對於非虛的成員來說,系統在編譯時,根據傳遞的引數 返回的型別等資訊決定實現何種操作。執行時的多型性 執行時的多型性就是指直到系統執行時,才根據實際情況決定實現何種操作。c 中,執行時的多型性通過虛成員實現。編...

C 多型的實現

封裝 繼承 多型,物件導向的三大特性,前兩項理解相對容易,但要理解多型,特別是深入的了解,對於初學者而言可能就會有一定困難了。我一直認為學習oo的最好方法就是結合實踐,封裝 繼承在實際工作中的應用隨處可見,但多型呢?也許未必,可能不經意間用到也不會把它跟 多型 這個詞對應起來。在此拋磚引玉,大家討論...