3.1如果同一作用域内的几个函数名字相同但形参列表不同,我们称之为重载函数。
3.1.1不允许两个函数除了返回类型外所有的要素都相同。(这也是很好解释的)
1 #include<iostream> 2 using namespace std; 3 int fuc(int a, double b) 4 { 5 cout<<"a= "<<a<<" "<<"b= "<<b<<endl; 6 return 0; 7 } 8 void fuc(int a, double b) 9 { 10 cout<<"a= "<<a<<" "<<"b= "<<b<<endl; 11 } 12 int main(void) 13 { 14 //如果允许只有返回类型不同,那么下面这个该调用谁呢? 15 fuc(3,3.14);//因为我们完全可以不关心返回值,所以这样的调用是很常见也是合法的,但是想要重载调用,就是非法的,因为编译器不知道该调用哪一个,二义性。 16 return 0; 17 }
3.1.2 有默认参数的重载测试
#include<iostream> using namespace std; int fuc(int a, double b=3.14) { cout<<"a= "<<a<<" "<<"b= "<<b<<endl; return 0; } int fuc(int a) { cout<<"a= "<<a<<endl; return 0; } int main(void) { fuc(10);//错误,此时编译器不知道到底调用谁,所以有默认实参的重载一定要小心,尤其在后面的类当中。 return 0; }
3.1.3 忽略了顶层const的重载
1 eg1: 2 #include<iostream> 3 using namespace std; 4 int fuc(int a) 5 { 6 cout << "a= " << a << endl; 7 return 0; 8 } 9 int fuc(const int a) 10 { 11 cout << "a= " << a << endl; 12 return 0; 13 } 14 int main(void) 15 { 16 fuc(10);//错误,依旧不能重载,顶层const会被忽略,具体见前面随笔的讲解 17 return 0; 18 } 19 20 eg2: 21 void test(const int *a) 22 { 23 24 } 25 void test(int *a) 26 { 27 28 } 29 int main(void) 30 { 31 int *a=nullptr; 32 test(a);//底层const可以重载,如果这里改成顶层const,依旧不能重载 33 return 0; 34 }
NOTE:
1、局部变量不能做默认实参。
2、重载函数的指针,指针类型必须与重载函数中的某一个的类型完全匹配,不能只匹配参数或者只匹配返回值的类型,必须完全匹配。
c++编译器可以处理重载函数名字一样的问题,如下面的fuc函数,fuc函数传递给函数指针的不会有错,根据你的函数指针指向的类型,你能调用对应的函数,注意要完全匹配。
如果下面的fuc函数 unsigend int参数的这个函数,如果函数指针调用的时候给了一个double参数,会有警告,因为double可以转换成unsigend int,这个和普通函数调用的转变一致。
1 int main(void) 2 { 3 void fuc(int *); 4 void fuc(unsigned int); 5 6 void(*pf1)(int)=fuc;//错误,没有任何一个与fuc的形参列表匹配 7 double(*pf2)(int *)=fuc;//错误,返回类型不匹配 8 9 return 0; 10 }