在物件導向的開發過程中,經常出現類的繼承,這裡面出現的成員函式的過載(overload)、覆蓋(override)與隱藏(hidden)很容易混淆。
首先澄清這3個概念:
過載 相同的範圍(在同乙個類中)
函式名字相同
引數不同
virtual 關鍵字可有可無
覆蓋(派生類函式覆蓋基類函式)
不同的範圍(分別位於派生類與基類)
函式名字相同
引數相同
基類函式必須有 virtual 關鍵字
隱藏(派生類的函式遮蔽了與其同名的基類函式)
如果派生類的函式與基類的函式同名,但是引數不同。此時,不論有無 virtual 關鍵字,基類的函式將被隱藏(注意別與過載混淆)
如果派生類的函式與基類的函式同名,並且引數也相同,但是基類函式沒有 virtual關鍵字。此時,基類的函式被隱藏(注意別與覆蓋混淆)
下面用乙個簡單的例子來闡述
例子中,pb和pd指向同一位址,按理執行結果是相同的,但其實卻不是。由於隱藏機制的作用,部分方法的呼叫依賴於所使用的指標!
由此看來,隱藏機制似乎會帶來不少理解上的問題,但「存在即合理」:
寫語句pd->f(10)的人可能真的想呼叫derived::f(char *)函式,只是他誤將引數寫錯了。有了隱藏規則,編譯器就可以明確指出錯誤,這未必不是好事。否則,編譯器會靜悄悄地將錯就錯,程式設計師將很難發現這個錯誤,留下禍根
假如類derived有多個基類(多重繼承) ,有時搞不清楚哪些基類定義了函式f。如果沒有隱藏規則,那麼pd->f(10)可能會呼叫乙個出乎意料的基類函式f,而隱藏規則的存在消滅了這個問題
總結工欲善其事,必先利其器。弄清楚這些基本概念,才能在實踐中少走彎路。
2017:
時隔7年再看,當年真是才疏學淺,c++根本沒有什麼隱藏規則,使用不同型別的指標雖然指向了同乙個物件,但是非虛函式並不會通過執行時虛表來繫結,反而是在編譯期靜態繫結,所以沒有什麼surprise,倒是在類繼承的設計上,確實埋了個坑,不過一般這種通過基類訪問不同子類例項的場景,對於public方法,應該都定義成virtual的以便擴充套件
不可不知的健康知識
健康最重要 晚上9 11點為免疫系統 淋巴 排毒時間,此段時間應安靜或聽 晚間11 凌晨1點,肝的排毒,需在熟睡中進行。凌晨1 3點,膽的排毒,亦同。凌晨3 5點,肺的排毒。此即為何咳嗽的人在這段時間咳得最劇烈,因排毒動作已走到肺 不應用止咳藥,以免抑制廢積物的排除。凌晨5 7點,大腸的排毒,應上廁...
不可不知的sudo命令
在linux運維工作中,每個人都應該各司其職。比如說運維經理掌握了root使用者,普通的運維人員一般人手乙個普通登入使用者。root使用者不簡單啊,建立使用者,日常重啟伺服器工作,以及一些其他的日常工作都是root使用者來完成的!很厲害吧!雖然運維經理是乙個super man,但是人家畢竟是經理嘛!...
不可不知的sudo命令
在linux運維工作中,每個人都應該各司其職。比如說運維經理掌握了root使用者,普通的運維人員一般人手乙個普通登入使用者。root使用者不簡單啊,建立使用者,日常重啟伺服器工作,以及一些其他的日常工作都是root使用者來完成的!很厲害吧!雖然運維經理是乙個super man,但是人家畢竟是經理嘛!...