什么是函數(shù)重載
如果同一個(gè)作用域內(nèi)的幾個(gè)函數(shù)名字相同但形參列表不同勋桶,我們稱之為重載(overload)函數(shù),C語言不支持重載臼氨,原因是這類函數(shù)編譯后的名稱是一樣的诸衔,而在C++中編譯后的名稱會(huì)因?yàn)樾螀⒌牟煌煌?/p>
判斷形參類型是否不同
有時(shí)候兩個(gè)形參列表看起來不一樣,實(shí)際上是一樣的集乔,如下代碼中三個(gè)函數(shù)都是一樣的:
typedef std::string MYSTRING;
int func(const std::string&); //省略了形參名
int func(const std::string& value);
int func(const MYSTRING&); //類型相同
重載和const形參
一個(gè)擁有頂層const的形參和另一個(gè)沒有頂層const的形參無法區(qū)分開來去件,下面兩個(gè)函數(shù)是一樣的。
int func(const std::string);
int func(std::string);
相反一個(gè)底層const形參和另一個(gè)沒有底層const的形參能區(qū)分開來扰路,下面兩個(gè)函數(shù)不一樣尤溜。
int func(const std::string*);
int func(std::string*);
由于非常量對(duì)象可以轉(zhuǎn)換為常量,所以上面的兩個(gè)函數(shù)都能作用于非常量對(duì)象汗唱,不過一般情況下宫莱,當(dāng)我們傳遞一個(gè)非常量對(duì)象或指向非常量對(duì)象的指針時(shí),編譯器會(huì)優(yōu)先選擇非常量版本的函數(shù)哩罪。
函數(shù)匹配
調(diào)用重載函數(shù)時(shí)授霸,有三種可能的結(jié)果:
- 編譯器找到一個(gè)與實(shí)參最佳匹配的函數(shù)巡验,并生成調(diào)用該函數(shù)的代碼。
- 找不到任何一個(gè)函數(shù)與調(diào)用的實(shí)參匹配碘耳,此時(shí)編譯出錯(cuò)显设。
- 有多于一個(gè)函數(shù)可以匹配,但是每一個(gè)都不是明顯的最優(yōu)選擇藏畅,此時(shí)也會(huì)出錯(cuò)敷硅,稱為二義性調(diào)用。
函數(shù)匹配的過程如下:
- 選定本次調(diào)用的候選函數(shù)愉阎,候選函數(shù)具備兩個(gè)特征绞蹦,一時(shí)與被調(diào)用函數(shù)同名,二是聲明在調(diào)用點(diǎn)可見榜旦。
- 從候選函數(shù)中選出可行函數(shù)幽七,可行函數(shù)也有兩個(gè)特征,一是其形參數(shù)量與本次調(diào)用的實(shí)參數(shù)量相等溅呢,二是每個(gè)實(shí)參的類型與對(duì)應(yīng)的形參類型相同或者能轉(zhuǎn)換成形參的類型澡屡。
- 尋找最佳匹配,逐一檢查實(shí)參咐旧,尋找形參類型與實(shí)參類型最匹配的那個(gè)可行函數(shù)驶鹉,比如精確匹配的比需要類型轉(zhuǎn)換的好。如果檢查了所有實(shí)參后沒有任何一個(gè)函數(shù)能脫穎而出铣墨,則編譯器報(bào)告二義性調(diào)用錯(cuò)誤室埋。
重載與作用域
如果我們?cè)趦?nèi)層作用域聲明名字,它將隱藏外層作用域中聲明的同名實(shí)體伊约,所以在不同的作用域中無法重載函數(shù)名姚淆。
void func(std::string value)
{
std::cout << value << std::endl;
}
int main()
{
void func(int value);//新作用域,隱藏了之前的func
system("pause");
return 0;
}