C++中關(guān)鍵字 override 的簡(jiǎn)析
在C++中,虛函數(shù)是最常見的實(shí)現(xiàn)多態(tài)的機(jī)制之一,來個(gè)最簡(jiǎn)單的例子溫習(xí)一下:
class Base // 基類 { public: virtual void f(){cout << "Base::f()" << endl;} }; class Derived1 : public Base // 派生類1 { virtual void f(){cout << "Derived1::f()" << endl;} }; class Derived2 : public Base // 派生類2 { virtual void f(){cout << "Derived2::f()" << endl;} };
以上是一個(gè)基類 Base
及其派生子類的最簡(jiǎn)示例,基類中有一個(gè)普通虛函數(shù) f( ),并且派生類們都復(fù)寫(即override
)了該虛函數(shù)。
以上代碼的含義再清楚不過:我們希望通過基類指針或者基類引用,可以調(diào)用派生類版本的函數(shù) f( ),以此實(shí)現(xiàn)所謂的多態(tài),如下代碼所示:
Base *b; b = new Derived1; b->f(); // 打印 "Derived1::f()" b = new Derived2; b->f(); // 打印 "Derived2::f()"
但,作為一名普通虛函數(shù) f( ),它實(shí)際上并不要求我們一定要復(fù)寫(即override
)它,假如你在派生類中不復(fù)寫它,那么派生類將很自然地使用基類所提供的備用版本。
危險(xiǎn)就在于此,人類是一個(gè)有諸多毛病的物種,其中一個(gè)根深蒂固的毛病是自以為是和粗心大意,因此以下代碼很有可能出自某個(gè)同胞之手:
class Derived3 : public Base // 派生類3 { // 注意:以下函數(shù)有參數(shù) // 人類以為復(fù)寫了基類虛函數(shù),但實(shí)際并沒有 virtual void f(int){cout << "Derived3::f()" << endl;} };
很明顯,這位同胞的本意與以上兩個(gè)派生類相同:派生出Derived3,并復(fù)寫虛函數(shù) f( )。很可惜,如果此時(shí)這位同胞貿(mào)然執(zhí)行如下代碼,將帶來災(zāi)難性的后果:
Base *b; b = new Derived3; b->f(); // 原想打印 "Derived2=3::f()" // 實(shí)際卻打印"Base::f()"!
如果這不夠?yàn)?zāi)難,可以將函數(shù) f( ) 想象成民航飛機(jī)的起飛引導(dǎo)程序。
現(xiàn)在問題很明顯了:
派生類的虛函數(shù)的復(fù)寫,很有可能出現(xiàn)烏龍——人類自以為復(fù)寫了基類的虛函數(shù)(比如 void f( ))
,但實(shí)際上卻寫了另一個(gè)函數(shù)(比如 void f(int))
,要命的是C++
語法并不制止這種愚蠢的行為,它會(huì)以為這是我們出于某種神秘的原因才這么干的。
然后,執(zhí)行程序,就這。。
解決辦法:
消除人類與編譯器之間深刻的誤會(huì),即:我們?cè)谙霃?fù)寫虛函數(shù)的時(shí)候,也同時(shí)將此想法明明白白地告訴編譯器,別讓它有什么誤會(huì)。怎么告訴它呢?蹬蹬噔噔憋了半天主角終于出場(chǎng)鳥:
class Derived3 : public Base // 派生類3 { // 注意: // 此處的 override 明明白白告訴編譯器:我要復(fù)寫虛函數(shù) // 但由于基類沒有 void f(int),因此此處將報(bào)錯(cuò)!哦也! virtual void f(int) override {cout << "Derived3::f()" << endl;} };
到此這篇關(guān)于C++中關(guān)鍵字 override
的簡(jiǎn)析的文章就介紹到這了,更多相關(guān)C++中關(guān)鍵字 override
內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語言超詳細(xì)講解數(shù)據(jù)結(jié)構(gòu)中的線性表
線性表,數(shù)據(jù)結(jié)構(gòu)中最簡(jiǎn)單的一種存儲(chǔ)結(jié)構(gòu),專門用于存儲(chǔ)邏輯關(guān)系為"一對(duì)一"的數(shù)據(jù)。線性表是基于數(shù)據(jù)在實(shí)際物理空間中的存儲(chǔ)狀態(tài),又可細(xì)分為順序表(順序存儲(chǔ)結(jié)構(gòu))和鏈表2022-05-05C++進(jìn)階練習(xí)刪除鏈表的倒數(shù)第N個(gè)結(jié)點(diǎn)詳解
這篇文章主要給大家介紹了關(guān)于如何利用C++刪除鏈表的倒數(shù)第N個(gè)結(jié)點(diǎn),文中通過實(shí)例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用C++具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2022-05-05基于C++實(shí)現(xiàn)簡(jiǎn)單的日期計(jì)算機(jī)
這篇文章主要為大家詳細(xì)介紹了如何基于C++實(shí)現(xiàn)簡(jiǎn)單的日期計(jì)算機(jī),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-04-04淺析C++模板類型中的原樣轉(zhuǎn)發(fā)和可變參數(shù)的實(shí)現(xiàn)
可變參數(shù)模板(variadic templates)是C++11新增的強(qiáng)大的特性之一,它對(duì)模板參數(shù)進(jìn)行了高度泛化,能表示0到任意個(gè)數(shù)、任意類型的參數(shù),這篇文章主要介紹了C++可變參數(shù)模板的展開方式,需要的朋友可以參考下2022-08-08