首先,在c++中,多型有兩種,函式過載和虛函式。(python中的多型貌似就是只有函式過載..)
粗俗地說:繼承意味著,子類可以使用父類的方法,而多型,則是父類可以使用子類的方法。
網上有一句話很好地解釋了多型:
多型性是允許你將父物件設定成為和乙個或更多的他的子物件相等的技術,賦值之後,父物件就可以根據當前賦值給它的子物件的特性以不同的方式運作。簡單的說,就是一句話:允許將子類型別的指標賦值給父類型別的指標。多型性在
object pascal
和c++
中都是通過虛函式(
virtual function
)實現的。
而為什麼要使用多型呢?
舉個栗子,乙個士兵類(父類),在一場戰役中,需要變成大刀兵作戰,那麼這時,他可以用大刀兵類(子類之一)的方法,例如**方法,刺刀方法。然後這名士兵,再另外異常戰役中,需要充當弓箭手,那麼他可以用弓箭手類(子類之一)的方法,例如拉弓方法,射箭方法等等。官方一點的說法,多型就是解耦。
那多型如何實現呢?
1.在父類中建立虛函式。
2.在子類中建立函式。 3.
父類的指標指向子類指標的引用
下面以**展示:
#includeusing namespace std;
class a
列印結果是:this is b
虛函式和純虛函式:
上面已經顯示出,虛函式,其實就是用 virtual 修飾的函式,而純虛函式則是用 virtual 修飾,且 =0 的函式,它本身沒有定義的。有乙個或多個純虛函式的類就叫做抽象類。雖然純虛函式自身沒有定義,但,它是用來提示使用者,它的子類們會有相應的定義,當然,這裡就是函式的過載了。
#includeusing namespace std;
class soilder
;class tank_soilder:public soilder
列印結果:create tanksoilder
create flysoilder
這片**顯示了 純虛函式的作用:例如 乙個兵營(父類),只能產生特殊兵種,不能產生赤手空拳的士兵(純虛函式),所以只能使用子類的方法來決定產生什麼兵。
虛函式是如何實現多型的?(下文的虛函式表 = 虛表)
首先要介紹虛表的概念,當乙個類中有虛函式時,編譯器就會給這個類建立乙個虛表,虛表上記載著,類中的虛函式的首位址。此外,編譯器還會給這個類自動新增乙個成員變數,是乙個指向虛表的指標(vptr),因此,在建立例項時,也會有乙個指向虛表的指標(cptr),個人理解,vptr和cptr其實是一樣的,只不過稱呼不同。
注意幾點:
1.虛表都放在每個類物件的首位址。例如: (int*)(&b) 表示虛表的首位址,b為乙個物件。 而 ((int*)*(int*)(&b))+0)表示虛表的第乙個虛函式位址
2.虛函式(首位址)在虛表中的排列順序是按照虛函式的宣告順序排的。
3.虛表中,父類的虛函式放在前面,子類的虛函式放在後面。
4.虛表中的虛函式可以被覆蓋,(這正是多型的本質。)看下圖:
父類的f()是虛函式,那麼子類的f()也會是虛函式.
(子類的虛表中,覆蓋的f()函式被放到了虛表中原來父類虛函式的位置。沒有被覆蓋的函式依舊。)
(又因為虛表位於類物件的首位址,所以,《若 a 為父類物件指標,&b為子類物件引用》當 a = &b 時,b的首位址賦了給a,所以導致a呼叫自己的f()時,卻會呼叫了
b 中同名的f( ))
需要注意的地方:
1.只有類的成員函式才能被宣告為虛函式,全域性函式或者靜態成員函式不能被宣告為虛函式
2.實現多型,並不是反正子類的虛表都會覆蓋父類的虛表,所以父類能呼叫所有子類的虛函式。父類能呼叫子類的虛函式,必須在父類中,有宣告其同名虛函式。
C 多型, 虛函式, 純虛函式
多型 不同物件接收相同的訊息產生不同的動作。多型包括 編譯時多型和 執行時多型 執行時多型是 通過繼承和虛函式來體現的。編譯時多型 運算子過載上。封裝可以隱藏實現細節,使得 模組化 繼承可以擴充套件已存在的 模組 類 它們的目的都是為了 重用。多型也有 重用的功能,還有解決專案中緊耦合的問題,提高程...
多型,虛函式,純虛函式
多型 借助虛函式,基類指標既可以使用基類 父類 的成員函式,也可以使用派生類 子類 的成員函式,它有多種形態,或多種表現方式,這就是多型 簡單說就是同一條語句可以執行不同的操作,看起來有不同表現方式,這就是多型。多型存在的三個條件 注意 派生類 子類 中的虛函式必須覆蓋 不是過載 基類 父類 中的虛...
C 多型 虛函式 純虛函式和抽象函式
多型 虛函式 純虛函式和抽象函式 多型按字面的意思就是多種形態。當類之間存在層次結構,並且類之間是通過繼承關聯時,就會用到多型。c 多型意味著呼叫成員函式時,會根據呼叫函式的物件的型別來執行不同的函式。其主要是函式的多種形態 乙個函式實現多種功能,形式是乙個乙個覆蓋。例項如下 includeusin...