默认参数
大约 5 分钟
默认参数

默认参数的目的
C++可以给函数定义默认参数值。通常,调用函数时,要为函数的每个参数给定对应的实参
void func1(int x, int y);
void func1(int x, int y)
{
cout << "x = " << x << endl;
cout << "y = " << y << endl;
}
无论何时调用func1函数,都必须要给其传递两个参数。但C++可以给参数定义默认值,如果将func1函数参数中的x定义成默认值0, y定义成默认值0,只需简单的将函数声明改成
void func1(int x = 0, int y = 0);
这样调用时,若不给参数传递实参,则func1函数会按指定的默认值进行工作。允许函数设置默认参数值,是为了让编程简单,让编译器做更多的检查错误工作。
调用效率问题(汇编)
若两个函数都传入,会提高效率,形参带默认值的函数;若传入,则效率不变。
int main() {
int a = 10;
int b = 20;
int ret = sum(a, b);
/*
mov eax, dword ptr[ebp-8]
push eax
mov ecx, dword ptr[ebp-4]
push ecx
call sum
*/
ret = sum(a);
/*
push 14H // 这里直接push省去mov
mov ecx, dword ptr[ebp-4]
push ecx
call sum
*/
//如果实参是立即数,则效率和默认参数是一样的
ret = sum();
ret = sum(30, 40);
/*
push 28H //40
push 1EH //30
call sum
*/
return 0;
}
int sum(int a = 10, int b = 20) {
return a + b;
}
- 当调用次数大的时候开销差别还是很可观
默认参数的声明
。,。若在定义时而不是在声明时置默认值,那么函数定义一定要在函数的调用之前。因为声明时已经给编译器一个该函数的向导,所以只在定义时设默认值时,编译器只有检查到定义时才知道函数使用了默认值。若先调用后定义,在调用时编译器并不知道哪个参数设了默认值。所以我们通常是将默认值的设置放在声明中而不是定义中。

/*error
int sum(int a = 10, int b); //error,默认值顺序从右往左赋值
int sum(int a, int b = 20);
*/
//下面的这种情况编译正常,原因:执行2的时已经知道了1给b赋了默认值(声明可以多次)
int sum(int a, int b = 20); //1
int sum(int a = 10, int b); //2
默认参数的顺序规定
如果一个函数中有多个默认参数,则形参分布中,默认参数应从右至左逐渐定义,因为涉及到参数的入栈出栈。当调用函数时,只能向左匹配参数。如:
void func2(int a = 1, int b, int c = 0, int d);//error
void func2(int a, int b, int c = 0, int d = 0);//ok
若给某一参数设置了默认值,那么在参数表中其后所有的参数都必须也设置默认值,否则,由于函数调用时可不列出已设置默认值的参数,编译器无法判断在调用时是否有参数遗漏。
默认参数与函数重载
默认参数可将一系列简单的重载函数合成为一个。例如:
void func3();
void func3(int x);
void func3(int x, int y);
//上面三个函数可以合成下面这一个
void func3(int x = 0, int y = 0);
如果一组重载函数(可能带有默认参数)都允许相同实参个数的调用,将会引起调用的二义性。
void func4(int);
void func4(int x, int y = 0);
void func4(int x = 0, int y = 0);
所以在。
课堂代码
#include <iostream>
using std::cout;
using std::endl;
#if 0
int add(){ return 1; }
int add(int x) { return x + 0 + 1; }
int add(int x,int y) { return x + y + 1; }
int add(int x,int y, int z) { return x + y + z; }
#endif
#if 0
//二义性
int add(int x, int y)
{
return x + y;
}
#endif
//默认参数要从右往左进行连续的赋初值
int add(int x = 0, int y = 0, int z = 0)
{
return x + y + z;
}
int main(int argc, char **argv)
{
int a = 3, b = 4, c = 5;
cout << "add(a, b, c) = " << add(a, b, c) << endl;
cout << "add(a, b) = " << add(a, b) << endl;//二义性
cout << "add(a) = " << add(a) << endl;
cout << "add() = " << add() << endl;
return 0;
}