在 C 中多型是如何實現的

2021-10-09 16:02:49 字數 1347 閱讀 5253

在 c++ 中,多型的實現是在基類的函式前加上 virtual 關鍵字使其成為虛函式,並在派生類中重寫該函式;該函式執行時會根據引用或指標繫結的物件的真實型別來決定要執行的版本。如果物件型別是派生類,就呼叫派生類的函式;如果物件型別是基類,就呼叫基類的函式。

多型性是物件導向程式設計(oop)的核心思想,其字面意思是多種形態。

當我們使用基類的引用或者指標呼叫基類中定義的乙個函式時,我們並不知道該函式真正作用的物件是什麼型別,它可能是乙個基類的物件也可能是乙個派生類的物件。如果該函式是虛函式,則直到執行時才會決定到底執行哪個版本,判斷的依據是引用或指標繫結的物件的真實型別。

另一方面,對非虛函式的呼叫和通過物件進行的函式(虛函式或非虛函式)呼叫在編譯時進行繫結。

對於某些函式,基類希望它的派生類各自定義適合自身的版本,此時基類就將這些函式宣告成虛函式。

基類通過在其成員函式的宣告語句之前加上關鍵字virtual使得該函式執行動態繫結。關鍵字 virtual 只能出現在類內部的宣告語句之前而不能用於類外部的函式定義。

任何建構函式之外的非靜態函式都可以是虛函式。

如果基類把乙個函式宣告成虛函式,則該函式在派生類中隱式地也是虛函式。當然,我們可以再一次使用 virtual 關鍵字指出該函式的性質。

在 c++11 中我們可以使用 override 關鍵字來說明派生類中的虛函式。如果我們使用 override 標記了某個函式,但該函式並沒有覆蓋已存在的虛函式,此時編譯器將報錯。

通常情況下,如果我們不使用某個函式,則無須為該函式提供定義。但是我們必須為每乙個虛函式都提供定義,而不管它是否被用到了,這是因為連編譯器也無法確定到底會使用哪個虛函式。

我們通過在函式體的位置(即在宣告語句的分號之前)書寫 =0 就可以將乙個虛函式說明為純虛函式。其中,=0 只能出現在類內部的虛函式宣告語句處。

和普通的虛函式不一樣,乙個純虛函式無需定義。我們可以將純虛函式的函式體定義在類的外部,但不能在類的內部為乙個 =0 的函式提供函式體。

含有(或者未經覆蓋直接繼承)純虛函式的類是抽象基類。抽象基類負責定義介面,而後續的其他類可以覆蓋該介面。我們不能(直接)建立乙個抽象基類的物件。

編譯器會為每個包含虛函式的類建立乙個虛函式表(或稱虛表),該表是乙個一維陣列,在這個陣列中存放每個虛函式的入口位址。編譯器會在每個物件的前四個位元組中儲存乙個虛表指標(即 vptr,一般作為類物件的第乙個成員),指向物件所屬類的虛表。

虛表和類是對應的,虛表指標和物件是對應的。在建構函式中進行虛表的建立和虛表指標的初始化。

C 中基於繼承的多型是如何實現的。

今日簡單地學了下基於繼承的多型,大致內容如圖所示。首先,要知道如何重寫父類方法。重寫父類方法就是修改它的實現,或者就是在子類中對繼承的父類方法重新編寫。在父類中用 virtual 關鍵字宣告的方法 俗稱虛擬方法 在子類中可以重寫。public virtual void dispaly 性別 年齡 t...

C 中多型的實現

物件導向語言的主要特點是 封裝性 繼承性 多型性。其中,封裝性使得 模組化,繼承性完成 的復用,多型實現介面的重用。在c 中,多型性是指具有不同功能的函式用同乙個函式名。即用同乙個函式名,呼叫不同內容的函式。下面主要從多型的實現分析c 中的多型。多型的實現有兩種方式 靜態聯編和動態聯編。系統在編譯的...

多型在C 中的應用

多型在c 中的應用 c 語言經過專門設計,以便不同庫中的基類 與派生類之間的版本控制可以不斷向前發展,同時保持向後相容。這具有多方面的意義。例如,這意味著在基類 中引入與派生類中的某個成員具有相同名稱的新成員在c 中是完全支援的,不會導致意外行為。它還意味著類必須顯式宣告某方法是要重寫乙個繼承方法,...