C++函數(shù)重載、隱藏與覆蓋重寫的精通指南
前言
對于C++函數(shù)而言,多個函數(shù)如果同名會有很多有意思的事情,從聲明的作用域來看,在橫向上同一個可訪問作用域里面的同名函數(shù)可以進(jìn)行重載;而縱向上作用域?qū)τ诟缸永^承的派生類來說,同樣的函數(shù)名稱可以實現(xiàn)隱藏與覆蓋。(如果基類成員函數(shù)是虛函數(shù),可以基于虛函數(shù)實現(xiàn)多態(tài),進(jìn)行動態(tài)聯(lián)編)下面就詳細(xì)介紹下函數(shù)的重載、隱藏與覆蓋重寫。
1 函數(shù)重載
- 定義:
C++規(guī)定在同一作用域中,例如一個類的成員函數(shù)之間,多個函數(shù)的名稱相同,但是各個函數(shù)的形式參數(shù)(指參數(shù)的個數(shù)、類型或者順序)不同時,構(gòu)成函數(shù)重載。
- 代碼示例
int test(int a); int test(int a, double b); int test(double b, int a); int test(int a, const char ** c); void test(int a, const char ** c); // 非重載,一起編譯會提示錯誤,僅僅返回值不同編譯無法區(qū)分使用的是那個重載函數(shù)
- 總結(jié)
- 前提:函數(shù)名稱相同,即要求是同名函數(shù);
- 重載作用域:函數(shù)重載發(fā)生在橫向水平的同一作用域,例如一個類成員函數(shù)之間的重載、全局函數(shù)之間的重載;
- 重載類型:無論是類的靜態(tài)成員函數(shù),還是類的普通成員函數(shù),亦或是普通的函數(shù),都可以形成重載;
- 重載要素:函數(shù)返回值類型函數(shù)重載無任何關(guān)系,僅僅返回值不同,形參相同的情況,會被禁止重載;
2 函數(shù)隱藏
- 定義
函數(shù)隱藏是說,在不同作用域中,定義的同名函數(shù)構(gòu)成函數(shù)隱藏(僅僅要求函數(shù)名稱相同,對于返回值和形式參數(shù)不做更多要求,并且對于是否是虛函數(shù)也不做要求)。例如派生類同名成員函數(shù)屏蔽與其基類的同名成員函數(shù),以及屏蔽同名全局外部函數(shù)。(經(jīng)常有人隱藏和覆蓋重寫弄混,所以提前說下,如果在派生類中存在與基類同名的虛函數(shù),并且返回值、形參都相同,則構(gòu)成函數(shù)重寫)。
- 代碼示例
#include <iostream> using namespace std; class Parent { public: void test(int a) { cout<<"this is Parent"<<endl; } }; class Son: public Parent { public: void test(int a) { cout<<"this is Son hide Parent function"<<endl; } }; int main(int argc, char ** argv) { Son son; son.test(1); return 0; }
? 輸出如下
root@localhost override [master] $ g++ --std=c++11 test_hide.cpp root@localhost override [master] $ ./a.out this is Son hide Parent function
- 總結(jié)
- 前提:函數(shù)名稱相同,即要求是同名函數(shù);
- 作用域:不在同一個橫向的作用域(分別位于派生類與基類的縱向作用域);
- 要素:返回類型可同可不同,參數(shù)亦可同可不同;
- 虛函數(shù):
參數(shù)不同,此時無論有無virtual關(guān)鍵字,基類的函數(shù)將被隱藏;
參數(shù)相同的情況下此時基類函數(shù)無virtual則屬于函數(shù)隱藏,后續(xù)無法繼續(xù)基于此利用這個函數(shù)的多態(tài)性;
如果是virtual則屬于函數(shù)重寫,繼續(xù)多態(tài)性的保留;
3 函數(shù)重寫
- 定義
函數(shù)的覆蓋和重寫是一個意思的兩個叫法,同時他的作用域也和函數(shù)隱藏相同,其實可以這么看,函數(shù)覆蓋和函數(shù)隱藏共同構(gòu)建了在具有集成關(guān)系的縱向作用域里面的同名函數(shù)的不同衍變,只不過函數(shù)覆蓋的條件更加嚴(yán)格些。
在介紹函數(shù)隱藏的時候,為了弄清楚函數(shù)隱藏與覆蓋重寫,也簡單描述了函數(shù)覆蓋。這里再進(jìn)一步進(jìn)行描述下:派生類中與基類中,同名函數(shù)的返回值類型、參數(shù)的都相同,并且基類中定義為虛函數(shù)的情況下,構(gòu)成虛函數(shù)覆蓋,也叫虛函數(shù)重寫。
- 代碼示例
#include <iostream> using namespace std; class Parent { public: virtual void test(int a) { cout<<"this is Parent"<<endl; } }; class Son: public Parent { public: void test(int a) { cout<<"this is Son Override Parent function"<<endl; } }; int main(int argc, char ** argv) { Son son; son.test(1); return 0; }
輸出如下:
root@localhost override [master] $ g++ --std=c++11 test_override2.cpp root@localhost override [master] $ ./a.out this is Son Override Parent function
附:令人迷惑的隱藏規(guī)則
C++的隱藏規(guī)則使問題復(fù)雜性陡然增加,這里“隱藏”是指派生類的函數(shù)屏蔽了與其同名的基類函數(shù),規(guī)則如下:
(1)如果派生類的函數(shù)與基類的函數(shù)同名,但是參數(shù)不同。此時,不論有無virtual關(guān)鍵字,基類的函數(shù)將被隱藏(注意別與重載混淆)。
(2)如果派生類的函數(shù)與基類的函數(shù)同名,并且參數(shù)也相同,但是基類函數(shù)沒有virtual關(guān)鍵字。此時,基類的函數(shù)被隱藏(注意別與覆蓋混淆)。
總結(jié)
咋一看,感覺重寫的功能基于隱藏是都可以實現(xiàn),那么為什么要區(qū)分重寫和隱藏呢?其實這是C++語言層面的問題了,C++基于virtual函數(shù)實現(xiàn)了多態(tài)性,并且可以進(jìn)行動態(tài)聯(lián)編,但是隱藏其實是破壞了這種多態(tài)性,也就是說父類成員函數(shù)的virtual性,在被子類成員函數(shù)的隱藏破壞后,無法傳遞給孫子類了,所以還需要重寫來遺產(chǎn)的家族傳遞。
- 前提:函數(shù)名稱相同,即要求是同名函數(shù);
- 作用域:不在同一個橫向的作用域(分別位于派生類與基類的縱向作用域);
- 要素:返回類型可同可不同,參數(shù)亦可同可不同;
- 是否虛函數(shù):前提是虛函數(shù),并且參數(shù)相同;
到此這篇關(guān)于C++函數(shù)重載、隱藏與覆蓋重寫的文章就介紹到這了,更多相關(guān)C++函數(shù)重載、隱藏與覆蓋重寫內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
c與c++之間的相互調(diào)用及函數(shù)區(qū)別示例詳解
這篇文章主要為大家介紹了c與c++相互調(diào)用的使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-06-06C語言sizeof和strlen的指針和數(shù)組面試題詳解
strlen是函數(shù),字符串長度,不包括停止符。而sizeof則是內(nèi)存塊的大小,包括停止符。數(shù)組是一種數(shù)據(jù)類型,數(shù)據(jù)類型的本質(zhì)就是固定大小,內(nèi)存塊的別名??梢杂胹izeof()一般都是數(shù)據(jù)類型2022-04-04

QT實現(xiàn)按鈕開關(guān)Form窗體的效果的示例代碼

在Visual Studio Code中配置C++編譯環(huán)境的問題