多型滿足條件
多型分為兩類
靜態多型: 函式過載 和 運算子過載屬於靜態多型,復用函式名。
動態多型: 派生類和虛函式實現執行時多型。
靜態多型和動態多型區別:
靜態多型的函式位址早繫結 - 編譯階段確定函式位址。
動態多型的函式位址晚繫結 - 執行階段確定函式位址。
建立乙個父類:
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 的多型
一 什麼是多型 物件導向程式設計中的另外乙個重要概念是多型性。在執行時,可以通過指向基類的指標,來呼叫實現派生類中的方法。可以把一組物件放到乙個陣列中,然後呼叫它們的方法,在這種場合下,多型性作用就體現出來了,這些物件不必是相同型別的物件。當然,如果它們都繼承自某個類,你可以把這些派生類,都放到乙個...