C++中過載、覆蓋和隱藏的區別以及適用場景
一、過載、覆蓋和隱藏的區別
二、適用場景
1、過載:
適用於不同的資料型別都需要使用到的功能函式。以資料相加的函式為例,可以在同一個檔案內提供以下的過載函式以支援同樣的功能:
int add(int, int);/*2個整數相加*/
int add(int, int, int);/*3個整數相加*/
double add(double, double);/*2個double型相加*/
特別的,形參為指標或引用時,指向的物件分別const和非const的情況,可以過載。比如下方的合併2個string的重置函式,根據實參的型別是否是const,編譯器可以自動選擇呼叫哪個:
string &stringCat(string*, string*);/*指向非const的*/
const string &stringCat(const string*, const string*)/*指向const,編譯通過,因為指標或引用指向的物件的型別不同*/
string &stringCat(string* const, string* const);/*編譯報錯。因為非const的引數可以轉換為const的,在傳入非const實參時第1和第3個函式都適用,所以編譯器認為1和3重複定義*/
編譯器會根據引數的型別、引數數量,自動選擇匹配的函式。注意引數相同、返回值型別不同的同名函式,不是過載的,編譯時會報錯。
2、覆蓋:
只能在類的繼承中使用。適用於父類和子類都要實現的成員函式,且該函式需要在執行中動態繫結的,這個函式就是虛擬函式,在動態繫結中子類的虛擬函式把父類的覆蓋了。
class Base{public: virtual func();};/*基類用virtual關鍵字定義了一個func()虛擬函式*/
class Child : public Base{public: func();};/*子類定義了一個同名、同參數、同返回值的函式,即是覆蓋*/
Base *pB; Bash B; Child C;
pB = &B; pB->func();/*動態繫結為Base物件,執行Base的func*/
pB = &C; pB->func();/*動態繫結為Child物件,執行Child的func*/
程式在執行時動態解析指標或引用指向的物件屬於哪個類,從而決定呼叫哪個類的成員函式。
3、隱藏
內層作用域的同名函式或同名變數,會影響外層作用域的同名函式和物件。唯一的例外就是虛擬函式的覆蓋。
一般建議除了通過覆蓋方式繼續來的虛擬函式外,派生的子類裡不要出現父類中使用的名字,避免隱藏。
三、其他一些技巧
1、虛擬函式也能過載
類的成員函式,無論是否是虛擬函式,都能被過載。但是如果派生類對虛擬函式進行覆蓋,則相應的過載函式會被隱藏。那麼問題來了,派生類怎麼才能訪問到這些隱藏的函式呢?
方法一:把所有過載函式都覆蓋一遍。
方法二:使用作用域說明符,顯式說明呼叫的物件。
方法三:使用using宣告語句,將外層的名稱拉入內層。這時派生類只需要實現部分的虛擬函式覆蓋,其他函式自動變為可見的過載函式。
Linux公社的RSS地址 : ofollow,noindex" target="_blank">https://www.linuxidc.com/rssFeed.aspx
本文永久更新連結地址: https://www.linuxidc.com/Linux/2018-10/155049.htm