好了,我們先來乙個小小的總結過載與覆蓋兩者之間的特徵
過載overload的特徵:
n 相同的範圍(在同乙個類中);
n 函式名相同引數不同;
n virtual 關鍵字可有可無。
覆蓋override是指派生類函式覆蓋基類函式,覆蓋的特徵是:
n 不同的範圍(分別位於派生類與基類);
n函式名和引數都相同;
n 基類函式必須有virtual 關鍵字。(若沒有virtual 關鍵字則稱之為隱藏hide)
如果基類有某個函式的多個過載(overload)版本,而你在派生類中重寫(override)了基類中的乙個或多個函式版本,或是在派生類中重新新增了新的函式版本(函式名相同,引數不同),則所有基類的過載版本都被遮蔽,在這裡我們稱之為隱藏hide。所以,在一般情況下,你想在派生類中使用新的函式版本又想使用基類的函式版本時,你應該在派生類中重寫基類中的所有過載版本。你若是不想重寫基類的過載的函式版本,則你應該使用例4或例5方式,顯式宣告基類名字空間作用域。
事實上,c++編譯器認為,相同函式名不同引數的函式之間根本沒有什麼關係,它們根本就是兩個毫不相關的函式。只是c++語言為了模擬現實世界,為了讓程式設計師更直觀的思維處理現實世界中的問題,才引入了過載和覆蓋的概念。過載是在相同名字空間作用域下,而覆蓋則是在不同的名字空間作用域下,比如基類和派生類即為兩個不同的名字空間作用域。在繼承過程中,若發生派生類與基類函式同名問題時,便會發生基類函式的隱藏。當然,這裡討論的情況是基類函式前面沒有virtual 關鍵字。在有virtual 關鍵字關鍵字時的情形我們另做討論。
繼承類重寫了基類的某一函式版本,以產生自己功能的介面。此時c++編繹器認為,你現在既然要使用派生類的自己重新改寫的介面,那我基類的介面就不提供給你了(當然你可以用顯式宣告名字空間作用域的方法,見[c++基礎]過載、覆蓋、多型與函式隱藏(1))。而不會理會你基類的介面是有過載特性的。若是你要在派生類裡繼續保持過載的特性,那你就自己再給出介面過載的特性吧。所以在派生類裡,只要函式名一樣,基類的函式版本就會被無情地遮蔽。在編繹器中,遮蔽是通過名字空間作用域實現的。
所以,在派生類中要保持基類的函式過載版本,就應該重寫所有基類的過載版本。過載只在當前類中有效,繼承會失去函式過載的特性。也就是說,要把基類的過載函式放在繼承的派生類裡,就必須重寫。
這裡「隱藏」是指派生類的函式遮蔽了與其同名的基類函式,具體規則我們也來做一小結:
n 如果派生類的函式與基類的函式同名,但是引數不同。此時,若基類無virtual關鍵字,基類的函式將被隱藏。(注意別與過載混淆,雖然函式名相同引數不同應稱之為過載,但這裡不能理解為過載,因為派生類和基類不在同一名字空間作用域內。這裡理解為隱藏)
n 如果派生類的函式與基類的函式同名,但是引數不同。此時,若基類有virtual關鍵字,基類的函式將被隱式繼承到派生類的vtable中。此時派生類vtable中的函式指向基類版本的函式位址。同時這個新的函式版本新增到派生類中,作為派生類的過載版本。但在基類指標實現多型呼叫函式方法時,這個新的派生類函式版本將會被隱藏。
n 如果派生類的函式與基類的函式同名,並且引數也相同,但是基類函式沒有virtual關鍵字。此時,基類的函式被隱藏。(注意別與覆蓋混淆,這裡理解為隱藏)。
n 如果派生類的函式與基類的函式同名,並且引數也相同,但是基類函式有virtual關鍵字。此時,基類的函式不會被「隱藏」。(在這裡,你要理解為覆蓋哦^_^)。
插曲:基類函式前沒有virtual關鍵字時,我們要重寫更為順口些,在有virtual關鍵字時,我們叫覆蓋更為合理些,戒此,我也希望大家能夠更好的理解c++中一些微妙的東西。費話少說,我們舉例說明吧。
例6#include
using namespace std;
class base//overload
virtual void fun(int i) //overload
};class derive : public base//override
void fun(int i) //override
void fun(int i,int j)
/*輸出結果
derive::fun()
derive::fun(int i)
derive::fun()
derive::fun(int i)
derive::fun(int i,int j)
press any key to continue
*/例7-1
#include
using namespace std;
class base
};class derive : public base{};
int main()
例7-2
#include
using namespace std;
class base
};class derive : public base
};int main()
例8-1
#include
using namespace std;
class base
};class derive : public base
};int main()
函式過載 覆蓋與隱藏
overload 翻譯過來就是 超載,過載,過載,超出標準負荷 override 翻譯過來是 重置,覆蓋,使原來的失去效果。先來說說過載的含義,在日常生活中我們經常要清洗一些東西,比如洗車 洗衣服。儘管我們說話的時候並沒有明確地說用洗車的方式來洗車,或者用洗衣服的方式來洗一件衣服,但是誰也不會用洗衣...
函式過載 隱藏與覆蓋
出現在相同作用域中的兩個函式,如果具有相同的名字而形參表不同,則稱為過載函式。作用 省去了為函式起名並記住函式名字的麻煩,簡化了程式的實現,使程式更容易理解。注意 main函式不能過載 函式不能僅僅基於不同的返回值型別而實現過載 進行函式過載時,要求同名函式在引數個數上不同,或者引數型別上不同 區域...
函式過載 覆蓋與隱藏
1 相同的範圍 在同乙個類中 2 函式名字相同 3 引數不同 4 有無virtual關鍵字不影響。呼叫實參與形參符合的那個函式。覆蓋是指派生類函式覆蓋基類函式。1 不同的範圍 分別位於派生類與基類 2 函式名字相同 3 引數相同 4 基類函式必須有ovirtual關鍵字,否則就是隱藏了。1 當派生類...