|
重載(overload):
必須在一個(gè)域中,函數(shù)名稱相同但是函數(shù)參數(shù)不同,重載的作用就是同一個(gè)函數(shù)有不同的行為,因此不是在一個(gè)域中的函數(shù)是無(wú)法構(gòu)成重載的,這個(gè)是重載的重要特征 覆蓋(override):
覆蓋指的是派生類的虛擬函數(shù)覆蓋了基類的同名且參數(shù)相同的函數(shù),既然是和虛擬函數(shù)掛鉤,說(shuō)明了這個(gè)是一個(gè)多態(tài)支持的特性,所謂的覆蓋指的是用基類對(duì)象的指針或者引用時(shí)訪問(wèn)虛擬函數(shù)的時(shí)候會(huì)根據(jù)實(shí)際的類型決定所調(diào)用的函數(shù),因此此時(shí)派生類的成員函數(shù)可以"覆蓋"掉基類的成員函數(shù)。 注意唯有同名且參數(shù)相同還有帶有virtual關(guān)鍵字并且分別在派生類和基類的函數(shù)才能構(gòu)成虛擬函數(shù),這個(gè)也是派生類的重要特征。 而且,由于是和多態(tài)掛鉤的,所以只有在使用類對(duì)象指針或者引用的時(shí)候才能使用上。 總之一句話:覆蓋函數(shù)都是虛函數(shù),反之不然~~ 隱藏(hide):
指的是派生類的成員函數(shù)隱藏了基類函數(shù)的成員函數(shù)。隱藏一詞可以這么理解:在調(diào)用一個(gè)類的成員函數(shù)的時(shí)候,編譯器會(huì)沿著類的繼承鏈逐級(jí)的向上查找函數(shù)的定義,如果找到了那么就停止查找了,所以如果一個(gè)派生類和一個(gè)基類都有同一個(gè)同名(暫且不論參數(shù)是否相同)的函數(shù),而編譯器最終選擇了在派生類中的函數(shù),那么我們就說(shuō)這個(gè)派生類的成員函數(shù)"隱藏"了基類的成員函數(shù),也就是說(shuō)它阻止了編譯器繼續(xù)向上查找函數(shù)的定義… 回到隱藏的定義中,前面已經(jīng)說(shuō)了有virtual關(guān)鍵字并且分別位于派生類和基類的同名,同參數(shù)函數(shù)構(gòu)成覆蓋的關(guān)系,因此隱藏的關(guān)系只有如下的可能: 1)必須分別位于派生類和基類中 2)必須同名 3)參數(shù)不同的時(shí)候本身已經(jīng)不構(gòu)成覆蓋關(guān)系了,所以此時(shí)是否是virtual函數(shù)已經(jīng)不重要了 當(dāng)參數(shù)相同的時(shí)候就要看時(shí)候有virtual關(guān)鍵字了,有的話就是覆蓋關(guān)系,沒(méi)有的時(shí)候就是隱藏關(guān)系了 覆蓋的函數(shù)是多態(tài)的,是存在于vtbl之中的函數(shù)才能構(gòu)成"覆蓋"的關(guān)系,而隱藏的函數(shù)都是一般的函數(shù),不支持多態(tài),在編譯階段就已經(jīng)確定下來(lái)了。
看出什么了嗎?下面說(shuō)明一下: (1)函數(shù)Derived::f(float)覆蓋了Base::f(float)。 (2)函數(shù)Derived::g(int)隱藏了Base::g(float),而不是重載。 (3)函數(shù)Derived::h(float)隱藏了Base::h(float),而不是覆蓋。 成員函數(shù)被重載的特征
(1)相同的范圍(在同一個(gè)類中); (2)函數(shù)名字相同; (3)參數(shù)不同; (4)virtual 關(guān)鍵字可有可無(wú)。 覆蓋是指派生類函數(shù)覆蓋基類函數(shù),特征是 (1)不同的范圍(分別位于派生類與基類); (2)函數(shù)名字相同; (3)參數(shù)相同; (4)基類函數(shù)必須有virtual 關(guān)鍵字。 “隱藏”是指派生類的函數(shù)屏蔽了與其同名的基類函數(shù),規(guī)則如下 (1)如果派生類的函數(shù)與基類的函數(shù)同名,但是參數(shù)不同。此時(shí),不論有無(wú)virtual關(guān)鍵字,基類的函數(shù)將被隱藏(注意別與重載混淆)。 (2)如果派生類的函數(shù)與基類的函數(shù)同名,并且參數(shù)也相同,但是基類函數(shù)沒(méi)有virtual 關(guān)鍵字。此時(shí),基類的函數(shù)被隱藏(注意別與覆蓋混淆) 3種情況怎么執(zhí)行:
1、重載:看參數(shù)
2、隱藏:用什么就調(diào)用什么
3、覆蓋:調(diào)用派生類
我們先來(lái)看一些代碼及其編譯結(jié)果。
實(shí)例一: class CB int main(int argc, char* argv[])
如果把派生CD中成員函數(shù)void f(int,int)的聲明改成和基類中一樣,即f(int),基類中的void f(int)還是一樣被隱藏,此時(shí)編譯不會(huì)出錯(cuò),在函數(shù)中test調(diào)用的是CD中的f(int) 所以,在基類中的某些函數(shù),如果沒(méi)有virtral關(guān)鍵字,函數(shù)名是f(參數(shù)是什么我們不管),那么如果在派生類CD中也聲明了某個(gè)f成員函數(shù),那么在類CD域中,基類中所有的那些f都被隱藏。 我們剛才說(shuō)的是沒(méi)有virtual的情況,如果有virtual的情況呢?? #include "stdafx.h" class CB int main(int argc, char* argv[]) 這么寫當(dāng)然是沒(méi)問(wèn)題了,在這里我不多費(fèi)口舌了,這是很簡(jiǎn)單的,多態(tài),虛函數(shù),然后什么指向基類的指針指向派生類對(duì)象阿,通過(guò)引用調(diào)用虛函數(shù)阿什么的,屬性多的很咯,什么??你不明白??隨便找本C++的書,對(duì)會(huì)講多態(tài)和虛函數(shù)機(jī)制的哦??! 那么如果基類CB中的函數(shù)f有關(guān)鍵字virtual ,但是參數(shù)和派生類CD中的函數(shù)f參數(shù)不一樣呢, class CB
void test() int main(int argc, char* argv[]) 編譯出錯(cuò)了, 通過(guò)上面三個(gè)例子,得出一個(gè)簡(jiǎn)單的結(jié)論 那么其他的情況呢??只要名字一樣,不滿足上面覆蓋的條件,就是隱藏了。 下面我要講最關(guān)鍵的地方了,好多人認(rèn)為,基類CB中的f(int)會(huì)繼承下來(lái)和CD中的f(int,int)在派生類CD中構(gòu)成重載,就像實(shí)例一中想像的那樣。
|
|
|