virtual
Virtual是C++ OO機制中很重要的一個關(guān)鍵字。只要是學(xué)過C++的人都知道在類Base中加了Virtual關(guān)鍵字的函數(shù)就是虛擬函數(shù)(例如函數(shù)print),于是在Base的派生類Derived中就可以通過重寫虛擬函數(shù)來實現(xiàn)對基類虛擬函數(shù)的覆蓋。當基類Base的指針point指向派生類Derived的對象時,對point的print函數(shù)的調(diào)用實際上是調(diào)用了Derived的print函數(shù)而不是Base的print函數(shù)。這是面向?qū)ο笾械亩鄳B(tài)性的體現(xiàn)。(關(guān)于虛擬機制是如何實現(xiàn)的,參見Inside the C++ Object Model ,Addison Wesley 1996)
class Base { public:Base(){} public:virtual void print(){cout<<"Base";} };class Derived:public Base { public:Derived(){} public:void print(){cout<<"Derived";} };int main() {Base *point=new Derived();point->print(); }Output: Derived這也許會使人聯(lián)想到函數(shù)的重載,但稍加對比就會發(fā)現(xiàn)兩者是完全不同的:
(1)?????? 重載的幾個函數(shù)必須在同一個類中;
覆蓋的函數(shù)必須在有繼承關(guān)系的不同的類中
(2)?????? 覆蓋的幾個函數(shù)必須函數(shù)名、參數(shù)、返回值都相同;
重載的函數(shù)必須函數(shù)名相同,參數(shù)不同。參數(shù)不同的目的就是為了在函數(shù)調(diào)用的時候編譯器能夠通過參數(shù)來判斷程序是在調(diào)用的哪個函數(shù)。這也就很自然地解釋了為什么函數(shù)不能通過返回值不同來重載,因為程序在調(diào)用函數(shù)時很有可能不關(guān)心返回值,編譯器就無法從代碼中看出程序在調(diào)用的是哪個函數(shù)了。
(3)?????? 覆蓋的函數(shù)前必須加關(guān)鍵字Virtual;
重載和Virtual沒有任何瓜葛,加不加都不影響重載的運作。
?
關(guān)于C++的隱藏規(guī)則:
我曾經(jīng)聽說過C++的隱藏規(guī)則:
(1)如果派生類的函數(shù)與基類的函數(shù)同名,但是參數(shù)不同。此時,不論有無virtual
關(guān)鍵字,基類的函數(shù)將被隱藏(注意別與重載混淆)。
(2)如果派生類的函數(shù)與基類的函數(shù)同名,并且參數(shù)也相同,但是基類函數(shù)沒有virtual
關(guān)鍵字。此時,基類的函數(shù)被隱藏(注意別與覆蓋混淆)。
bp 和dp 指向同一地址,按理說運行結(jié)果應(yīng)該是相同的,而事實上運行結(jié)果不同,所以他把原因歸結(jié)為C++的隱藏規(guī)則,其實這一觀點是錯的。決定bp和dp調(diào)用函數(shù)運行結(jié)果的不是他們指向的地址,而是他們的指針類型。“只有在通過基類指針或引用間接指向派生類子類型時多態(tài)性才會起作用”(C++ Primer 3rd Edition)。pb是基類指針,pd是派生類指針,pd的所有函數(shù)調(diào)用都只是調(diào)用自己的函數(shù),和多態(tài)性無關(guān),所以pd的所有函數(shù)調(diào)用的結(jié)果都輸出Derived::是完全正常的;pb的函數(shù)調(diào)用如果有virtual則根據(jù)多態(tài)性調(diào)用派生類的,如果沒有virtual則是正常的靜態(tài)函數(shù)調(diào)用,還是調(diào)用基類的,所以有virtual的f函數(shù)調(diào)用輸出Derived::,其它兩個沒有virtual則還是輸出Base::很正常啊,nothing surprise!?
所以并沒有所謂的隱藏規(guī)則,雖然《高質(zhì)量C++/C 編程指南》是本很不錯的書,可大家不要迷信哦。記住“只有在通過基類指針或引用間接指向派生類子類型時多態(tài)性才會起作用”。
轉(zhuǎn)載于:https://www.cnblogs.com/yuandonghua/p/10531753.html
總結(jié)
- 上一篇: VCL界面控件DevExpress VC
- 下一篇: [转帖]面包屑设计