C 多型三種實現方式

2021-10-24 18:26:05 字數 1804 閱讀 4677

定義

多型的定義簡單來說就是使一條語句有多種狀態。

實現方式

多型的實現方式分為三塊:過載、重寫、重定義。下面我們來談一談他們各自的實現方式和實現原理。

過載實現方式

過載是在同一作用域內(不管是模組內還是類內,只要是在同一作用域內),具有相同函式名,不同的形參個數或者形參型別。返回值可以相同也可以不同(在函式名、形參個數、形參型別都相同而返回值型別不同的情況下無法構成過載,編譯器報錯。這個道理很簡單,在函式呼叫的時候是不看返回值型別的)。

實現原理

過載是一種靜態多型,即在編譯的時候確定的。c++實現過載的方式是跟編譯器有關,編譯過後c++的函式名會發生改變,會帶有形參個數、型別以及返回值型別的資訊(雖然帶有返回值型別但是返回值型別不能區分這個函式),所以編譯器能夠區分具有不同形參個數或者型別以及相同函式名的函式。插一句,在c語言中編譯器編譯過後函式名中不會帶有形參個數以及型別的資訊,因此c語言沒有過載的特性。由此帶來麻煩的一點是如果想要在c++中呼叫c語言的庫,需要特殊的操作(extern 「c」{})。庫中的函式經過c編譯器編譯的話會生成不帶有形參資訊的函式名,而用c++的編譯器編譯過後會生成帶有形參資訊的函式名,因此將會找不到這個函式。extern 「c」{}的作用是使在這個作用域中的語句用c編譯器編譯,這樣就不會出錯。這也是一種語言相容性的問題。

重寫實現方式

重寫是在不同作用域內(乙個在父類乙個在子類),函式名、形參個數、形參型別、返回值型別都相同並且父類中帶有virtual關鍵字(換言之子類中帶不帶virtual都沒有關係)。有一種特殊的情況:函式返回值型別可以不同但是必須是指標或者引用,並且兩個虛函式的返回值之間必須要構成父子類關係。這種情況稱之為協變,也是一種重寫。引入協變的好處是為了避免危險的型別轉換。

實現原理

重寫是一種動態多型,即在執行時確定的。c++實現重寫的方式也跟編譯器有關,編譯器在例項化乙個具有虛函式的類時會生成乙個vptr指標(這就是為什麼靜態函式、友元函式不能宣告為虛函式,因為它們不例項化也可以呼叫,而虛函式必須要例項化,這也是為什麼建構函式不能宣告為虛函式,因為你要呼叫虛函式必須得要有vptr指標,而建構函式此時還沒有被呼叫,記憶體中還不存在vptr指標,邏輯上矛盾了)。vptr指標在類的記憶體空間中佔最低位址的四位元組。vptr指標指向的空間稱為虛函式表,vptr指標指向其表頭,在虛函式表裡面按宣告順序存放了虛函式的函式指標,如果在子類中重寫了,在子類的記憶體空間中也會產生乙個vptr指標,同時會把父類的虛函式表copy一下當做自己的,然後如果在子類中重新宣告了虛函式,會按宣告順序接在父類的虛函式函式指標下。而子類中重寫的虛函式則會替換掉虛函式表中原先父類的虛函式函式指標。重點來了,在呼叫虛函式時,不管呼叫他的是父類的指標、引用還是子類的指標、引用,他都不管,只看他所指向或者引用的物件的型別(這也稱為動態聯編),如果是父類的物件,那就呼叫父類裡面的vptr指標然後找到相應的虛函式,如果是子類的物件,那就呼叫子類裡面的vptr指標然後找到相應的虛函式。當然這樣子的過程相比靜態多型而言,時間和空間上的開銷都多了(這也是為什麼內聯函式為什麼不能宣告為虛函式,因為這和內聯函式加快執行速度的初衷相矛盾)。

重定義實現方式

重定義是在不同作用域內的(乙個在父類乙個在子類),只要函式名相同,且不構成重寫,均稱之為重定義

實現原理

重定義的實現原理跟繼承樹中函式的尋找方式有關,他會從當前物件的類作用域內開始查詢同名的函式,如果沒有找到就一直向上查詢直到基類為止。如果找到乙個同名的函式就停止。這也就說明他不管函式的形參型別或者個數是不是一樣,只要函式名一樣,他就認為是找到了,如果這時候形參型別或者個數不一致,編譯器就會報錯。多重繼承的查詢,如果在同一層內出現一樣的函式宣告那麼編譯器會報錯不知道呼叫哪乙個函式,這類問題也叫鑽石繼承問題。鑽石問題的解決方案可以通過虛繼承來實現,這樣就不會存在多個一樣的函式宣告。

C 多型 以及實現多型的三種方式

實實在在說多型 c 篇 1.什麼是多型.1 2.多型帶來的好處.1 3.c 中實現多型的方式.1 4.細說用函式過載實現的多型.2 5.細說用模板函式實現的多型.3 6.小結.4 7.細說用虛函式實現的多型.4 7.1.虛函式是怎麼回事.4 7.2.向上轉型.5 7.3.為什麼要用指標或引用來實現動...

C 多型的三種實現方式 小結

c 實現多型主要有3種方法,虛方法,抽象類,介面 在父類的方法前面加關鍵字virtual,子類重寫該方法時在方法名前面加上override關鍵字,例如下面的person類的sayhello方法 class p程式設計客棧erson string name public string name 父類方...

C 介面的三種實現方式

原文c 介面的三種實現方式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 4...