简介定义
C++默认参数指的是当函数调用中省略了实参时自动使用的一个值。写法如下:
void foo(int a = 1)
{
}
void foo(int a, int b=1, int c=1)
{
}
默认参数有两个规则,
- 规则一:从第一个出现默认参数的参数开始,后面的参数必须也指定默认参数
void foo(int a=1, int b, int c=1); //错误
void foo(int a=1, int b, int c); //错误
void foo(int a, int b, int c=1); //正确
void foo(int a, int b=1, int c=1); //正确
void foo(int a=1, int b=1, int c=1); //正确
- 规则二:声明和定义分开时,仅声明处做初始赋值动作
void foo(int a = 1);
void foo(int a)
{
}
分析原理
在我的理解中,C++的各种特性基本是靠编译器隐藏了很多特殊操作,来实现这些特性,诸如面向对象等等。实际纯C语言结合一些编译器选项,完全可以实现C++的绝大多数效果。所以直接看汇编,扒开编译器隐藏的细节,到汇编这一层基本原形必露,借助Compiler Explorer:

对比发现有没有默认参数两者汇编一模一样,那为什么可以实现不同的效果呢?再看下如果调用一下这2个函数:

可以看到如果不给默认参数赋值,则在调用处会由编译器自动给参数赋值为默认值,如果你指定了参数值,就用你指定的。也就是说编译器玩了个花招而已,并没多牛逼。
了解了实现原理后,再分析下为什么有上面的两个规则约束。假设带默认参数的函数可以这样定义:
int foo(int a = 1, int c);
按照它的特性,可以在调用处以这几种形式调用:
foo(1);//本意是a使用默认值a=1,c使用传递的值c=1
foo(1);