C 物件導向 23 多型原理剖析

2021-10-06 05:56:25 字數 1701 閱讀 8940

前面一篇學習了多型,有靜態多型和動態多型之分。動態繫結是第一需要繼承關係,第二是子類需要重寫父類的函式。什麼是重寫,從函式返回值,函式名稱和引數列表一模一樣才叫函式重寫。本篇就借助vs 開發工具來捋一捋多型的底層原理。

1.兩個單詞概念

在前面多繼承的時候,我們也介紹了虛繼承,其中使用了virtual,當時有vbptr虛基類指標和vbtable虛基類表,其中作用是vbptr指向了vbtable。這次多型底層原理學習也需要理解類似的兩個概念。

虛函式指標 vfptr,vritual function pointer

虛函式表 vftable, virtual function table

虛函式指標的作用是指向虛函式表。

2.不帶virtual的animal類佔記憶體大小

**和前面一篇一樣,當前這裡操作需要刪除**中animal基類虛函式前面vritual,先看看這個父類不帶virtual所佔記憶體大小

不帶virtual,而且當前anima類沒有什麼成員變數,所以所佔記憶體就1個位元組。

2.帶virtual的animal類佔記憶體大小

在animal基類中加上virtual,執行上面命令,看看佔記憶體是多少

加上virtual關鍵字之後,所佔記憶體為4位元組,不用懷疑和亂猜測,這裡四個位元組就是乙個指標大小,前面學習過,任何型別的指標所佔記憶體大小都是4位元組,這裡這個指標就是vfptr,也就是文章開頭的虛函式指標。注意上面,這個vfptr指向vftable,在虛函式表中,當前儲存的是 &animal::speak,animal::這個是作用域,表示儲存的是animal類的speak函式,前面加上&符號,就表示animal類中speak函式的位址。

3.靜態繫結的時候子類cat中儲存內容

現在我們又來去除基類animal中虛函式前面的關鍵字virtual,把上面命令變成查詢子類cat的繼承關係情況。

這個時候,子類中可以看到父類是animal, 而且子類所佔記憶體大小1位元組,這裡沒有vfptr,也就是虛函式指標,子類繼承父類的全部,所以呼叫speak函式,輸出的內容是父類中speak函式的結果。

4.動態繫結子類cat中儲存的內容

把前面刪除關鍵字virtual新增回來,再次查詢子類cat的繼承關係

這個時候動態繫結,子類cat中顯示父類是animal, 還有乙個虛函式指標,這個是父類繼承過來的,所以位元組大小是4。這個時候虛函式指標指向虛函式表,此時虛函式表中儲存的是&cat::speak 這個很清楚寫明白了,儲存的是子類cat作用域下speak函式的記憶體位址。所以,動態繫結下,dospeak函式傳入引數是什麼子類物件,就呼叫該子類物件中的speak方法。因為虛函式表中用子類中的同名函式覆蓋了原來父類的虛函式。

C 物件導向 多型

一 對於繼承自同一基類的多個不同派生類的例項,在執行時可以將它們賦值給基類型別的變數,訪問該變數的同乙個成員會根據該變數執行時型別的不同而產生不同的行為,這個特性即被稱為多型 polymorphism 多型允許以同一種方式訪問同乙個變數的成員而產生不同的行為 1.在c 中,每個型別都是多型的,因為包...

多型的原理剖析

多型滿足條件 多型分為兩類 靜態多型 函式過載 和 運算子過載屬於靜態多型,復用函式名。動態多型 派生類和虛函式實現執行時多型。靜態多型和動態多型區別 靜態多型的函式位址早繫結 編譯階段確定函式位址。動態多型的函式位址晚繫結 執行階段確定函式位址。建立乙個父類 class animal 當不加vir...

Python 23 物件導向2 繼承,多型

3.多繼承 4.新式類和舊式類 5.多型基本概念 6.類屬性 類方法 classmethod 7.靜態方法 staticmethod 8.案例分析 物件導向三大特性 封裝 定義類的準則 繼承 實現 的重用 多型 增加 的靈活度 繼承 實現 的重複的使用,將多個類的共有方法封裝在父類中,個性類從父親類...