多型的原理剖析

2021-10-20 18:28:26 字數 1917 閱讀 9885

多型滿足條件

多型分為兩類

靜態多型: 函式過載 和 運算子過載屬於靜態多型,復用函式名。

動態多型: 派生類和虛函式實現執行時多型。

靜態多型和動態多型區別:

靜態多型的函式位址早繫結 - 編譯階段確定函式位址。

動態多型的函式位址晚繫結 - 執行階段確定函式位址。

建立乙個父類:

class

animal

};

當不加virtual時sizeof(animal)可以發現占用乙個位元組。(這是因為此時animal類中只有乙個成員函式,相當於乙個空類)

為什麼空類只占用乙個位元組?

在c++中空類會佔乙個位元組,這是為了讓物件的例項能夠相互區別。具體來說,空類同樣可以被例項化,並且每個例項在記憶體中都有獨一無二的位址,因此,編譯器會給空類隱含加上乙個位元組,這樣空類例項化之後就會擁有獨一無二的記憶體位址。如果沒有這乙個位元組的佔位,那麼空類就無所謂例項化了,因為例項化的過程就是在記憶體中分配一塊位址。

總而言之乙個位元組是佔位用的。

為什麼成員函式不占用類或者物件的空間?

成員函式可以被看作是類作用域的全域性函式,不在物件分配的空間裡,只有虛函式才會在類物件裡有乙個指標,存放虛函式的位址等相關資訊。

成員函式的位址,編譯期就已確定並靜態繫結或動態的繫結在對應的物件上,物件呼叫成員函式時,編譯器可以確定這些函式的位址,並通過傳入this指標和其他引數,完成函式的呼叫,所以類中就沒有必要儲存成員函式的資訊

當加上virtual時sizeof(animal)可以發現占用四個位元組。(此時內部包含乙個名為vfptr(虛函式指標)的指標去指向vftable(虛函式表),表中記錄父類speak函式位址)。

子類繼承父類:

class

cat:

public

animal};

class

dog:

public

animal

};

當子類沒有內容的時候(也即沒有重寫父類的虛函式的時候),子類會繼承父類所有的內容,包括父類的虛函式表。

當子類重寫父類的虛函式表時,子類中的虛函式表內部會替換成重寫後的子類的虛函式位址。

當父類的指標或引用指向子類的物件的時候,會查詢物件的虛函式表,進入重寫後子類虛函式表中的函式位址入口,從而就會呼叫子類的cat作用範圍下的speak函式位址,從而實現多型。

cat cat;

animal &animal = cat;

animal.

speak()

;

此時animal指標指向的是cat的子類物件,因此去找cat的speak位址,即在執行階段發生動態的多型。

C 多型的基本語法與原理剖析

多型分為兩類 1.靜態多型 函式過載和運算子過載屬於靜態多型,復用函式名 2.動態多型 派生類和虛函式實現執行時多型 首先讓我們看這段 include using namespace std class animal class cat public animal void dospeak anim...

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

前面一篇學習了多型,有靜態多型和動態多型之分。動態繫結是第一需要繼承關係,第二是子類需要重寫父類的函式。什麼是重寫,從函式返回值,函式名稱和引數列表一模一樣才叫函式重寫。本篇就借助vs 開發工具來捋一捋多型的底層原理。1.兩個單詞概念 在前面多繼承的時候,我們也介紹了虛繼承,其中使用了virtual...

剖析C 的多型

一 什麼是多型 物件導向程式設計中的另外乙個重要概念是多型性。在執行時,可以通過指向基類的指標,來呼叫實現派生類中的方法。可以把一組物件放到乙個陣列中,然後呼叫它們的方法,在這種場合下,多型性作用就體現出來了,這些物件不必是相同型別的物件。當然,如果它們都繼承自某個類,你可以把這些派生類,都放到乙個...