C/C++默认实参学习
今天重点学习C/C++的默认实参。不多说,下面开始进入正题。
默认实参
引用《C++大学教程》里面的话:默认实参必须是函数形参列表中最靠右边(尾部)的形参。当调用两个或者多个默认实参的函数时,如果省略的实参不是形参列表中最靠右边的,那么在该实参后面的参数全部都该省略。
默认实参定义和使用
非成员函数的默认实参
- 如果函数的定义作为函数的原型出现,则直接在函数定义中设置默认实参。
int add(int a = 1, int b = 1){ return a+b; } int main(){ cout << add() << endl;//省略2个实参 cout << add(2) << endl; //省略一个实参 return 0; } |
|
-
存在函数声明, 那么因该在函数声明中设置。注意,如果同时才函数声明和函数定义中设置默认实参,会导致编译错误;如果只在函数定义中设置,会导致设置无效。
- 函数定义和函数声明同时出现,应该在函数声明中设置默认参数。
int add(int a = 1, int b = 1);//默认参数a = 1, b = 1
int main(){ cout << add() << endl;//省略2个实参 cout << add(2) << endl; //省略一个实参 return 0; }
int add(int a, int b){ return a + b; } |
- 如果在函数声明和函数定义中同时设置了默认实参,会导致编译错误。
int add(int a = 1, int b = 1);//默认参数a = 1, b = 1
int main(){ cout << add() << endl;//省略2个实参 cout << add(2) << endl; //省略一个实参 return 0; }
int add(int a = 1, int b =1){ //函数定义中也设置了实参,结果导致编译错误 return a + b; } |
G:\users\lichanglou\CodeBlocks\C++默认实参的学习\main.cpp|13|error: default argument given for parameter 1 of 'int add(int, int)' [-fpermissive]| G:\users\lichanglou\CodeBlocks\C++默认实参的学习\main.cpp|13|error: default argument given for parameter 2 of 'int add(int, int)' [-fpermissive]| |
- 如果在函数定义中设置默认实参,将会导致默认实参设置无效。在调用该函数时如果省略默认实参同样也会导致编译错误。
int add(int a, int b);//函数声明中未设置默认实参
int main(){ cout << add() << endl;//省略2个实参,导致编译出错 cout << add(2) << endl; //省略一个实参,同样编译出错 return 0; }
int add(int a = 1, int b =1){ //函数定义中设置默认实参 return a + b; } |
G:\users\lichanglou\CodeBlocks\C++默认实参的学习\main.cpp|8|error: too few arguments to function 'int add(int, int)'| |
-
编译器如何区分重载的函数和省略默认实参的调用?
int add( int a, int b, int c =10){//有3个参数,并在设置第3个默认实参c = 10
return a+b+c;
}
int add( int a, int b){//重载add函数,但是只有2个参数
return a+b;
}
int main(){
cout << add(1, 1) << endl;//这里编译器无法识别调用哪个函数,编译错误
return 0;
}
G:\users\lichanglou\CodeBlocks\C++默认实参的学习\main.cpp|13|error: call of overloaded 'add(int, int)' is ambiguous|
类的成员函数的默认实参设置
类的成员函数的默认既可以在类的定义中设置,也可以在类的实现中设置,但不能同时设置。
- 在类的定义中设置
class A{//类A的声明 public: int add(int a =1, int b =1);//在类的定义中设置了默认实参。
}; int A::add(int a, int b){//成员函数add的实现。 return a+b; }
int main(){ A a; cout << a.add() << endl;// return 0; } |
结果正常运行,输出2 |
- 在成员函数的实现中设置默认实参
class A{//类A的定义 public: int add(int, int);//成员函数的声明,并未设置默认实参
}; int A::add(int a=1, int b=1){//成员函数add的实现。设置默认实参a=1, b=1 return a+b; }
int main(){ A a; cout << a.add() << endl;// return 0; } |
结果正常运行,输出2 |
- 在成员函数定义和声明中同时出现
class A{//类A的定义 public: int add(int a=1, int b=1);//成员函数的声明,设置默认实参a=1,b=1
}; int A::add(int a=1, int b=1){//成员函数add的实现。设置默认实参a=1, b=1 return a+b; }
int main(){ A a; cout << a.add() << endl;// return 0; } |
G:\users\lichanglou\CodeBlocks\C++默认实参的学习\main.cpp|9|error: default argument given for parameter 2 of 'int A::add(int, int)' [-fpermissive]| |
总结
1、对非类的成员函数来说,如果没有函数声明,那么就在函数定义里面设置默认实参,如果存在函数声明,则只能在函数声明中设置。而对于类的成员函数来说,既可以在声明时设置,也可以在实现时设置。
2、对于非类的成员函数和类的成员函数,都不能在声明和实现中同时定义默认实参。
3、对于重载的函数和省略默认实参的函数的调用,编译器无法区分?这点还需要进一步学习。