以下面的例子來進行研究:
#include <iostream>
#include <cstdio>
using namespace std;
double add(double x,double y)
{
return x+y;
}
int add(int x,int y)
{
return x+y;
}
int main()
{
int a=1,b=2;
double c=1.00,d=2.00;
cout<<add(a,b)<<endl;
add(c,d);
//構成重載的條件:1.參數個數不同 2.參數類型不同 3.參數順序不同
//返回值不同不能構成重載
return 0;
}
重載函數準則如下:
1.將所有同名函數作爲候選者
即例子中2個add函數都可能被main函數中的add所調用。
2.嘗試尋找可行的候選函數:
1 )精確匹配實參
例子中的第一個add調用中的實參a,b都爲int型,與第一個add函數匹配,所以調用第一個add函數;第二個add調用中的實參c,d都爲double型,與第二個add函數匹配,所以調用第二個函數
運行結果如下:
2) 通過默認參數能夠匹配實參
將int型add函數添加一個默認參數
int add(int x,int y,int z=1)
{
return x+y+z;
}
運行結果如下:
4爲傳進來的實參a=1,b=2與默認參數z=1的和。
3) 通過默認類型轉換匹配實參
將main函數改爲如下:
int main()
{
char a='q',b='w';
double c=3.00,d=4.00;
cout<<add(a,b)<<endl;
add(c,d);
cout<<add(c,d)<<endl;
return 0;
}
將int型的a,b改爲char型。
運行結果如下:
運行結果中的232即爲q,w的ascll碼之和,說明通過默認類型轉換匹配實參。
此時,又有一個新的問題:char型的add調用時轉換成了哪個類型?int 還是doouble?
於是我進行如下測試:
測試1:
將double型的add函數修改如下:
double add(double x,double y)
{
return y-x;
}
運行結果如下:
說明char型的add優先調用int型add函數
測試2:
將int型的add函數註釋掉
運行結果如下:
6爲w與q的ascll碼之差,說明此時char型的add調用了double型的add函數。
3.匹配失敗:
1) 最終尋找到的可行候選函數不唯一,則出現二義性,編譯失敗。
添加一個帶有一個默認參數的int型函數,其他和上一個int型函數一樣
int add(int x,int y)
{
return x+y;
}
int add(int x,int y,int z=0)
{
return x+y+z;
}
運行結果如下:
說明有歧義的函數重載不可行,應該避免。
2) 無法匹配所有候選者,函數未定義,編譯失敗。