Default value of function parameter
1。
1 2 3 4 5 | int Add (int a, int b = 3); int Add (int a, int b) { } |
2。
1 2 3 4 5 | int Add (int a, int b); int Add (int a, int b = 3) { } |
这是一个标准的工作方式,和为什么?
如果将声明放在头文件中,定义放在单独的
具体来说,假设:
磅1 | int Add(int a, int b); |
LIB CPP
1 2 3 | int Add(int a, int b = 3) { ... } |
测试程序
1 2 3 4 5 | #include"lib.h" int main() { Add(4); } |
因此,默认参数定义通常在函数声明中指定:
磅1 | int Add(int a, int b = 3); |
在C++中,在参数列表中对默认参数施加的要求如下:
必须多次指定给定参数的默认参数。多次指定(即使具有相同的默认值)是非法的。
带有默认参数的参数必须在参数列表的末尾形成一个连续的组。
现在,记住这一点,在C++中,只要满足上述要求,就允许"从一个函数声明到下一个参数"的"增长"参数集。
例如,可以声明一个没有默认参数的函数
1 | void foo(int a, int b); |
为了在声明之后调用该函数,您必须显式地指定这两个参数。
稍后(下一步)在同一个翻译单元中,您可以再次声明它,但这次使用一个默认参数
1 | void foo(int a, int b = 5); |
从这一点上,你可以用一个明确的论点来称呼它。
再往下,您可以再次声明它,添加一个默认参数。
1 | void foo(int a = 1, int b); |
从这一点上,你可以不用显式的参数来调用它。
完整的示例如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | void foo(int a, int b); int main() { foo(2, 3); void foo(int a, int b = 5); // redeclare foo(8); // OK, calls `foo(8, 5)` void foo(int a = 1, int b); // redeclare again foo(); // OK, calls `foo(1, 5)` } void foo(int a, int b) { // ... } |
至于您所讨论的代码,这两种变体都是完全有效的,但它们的含义不同。第一个变量立即为第二个参数声明默认参数。第二个变量最初声明您的函数没有默认参数,然后为第二个参数添加一个。
两个声明的净效果(即第二个声明后面的代码看到它的方式)完全相同:函数的第二个参数有默认参数。但是,如果您设法在第一个和第二个声明之间挤压一些代码,那么这两个变体的行为会有所不同。在第二个变量中,函数在声明之间没有默认参数,因此必须显式指定这两个参数。
第一种方法比第二种方法更好。
这是因为头文件将显示参数是可选的,以及它的默认值是什么。此外,这将确保默认值相同,无论相应的.cpp文件的实现如何。
第二种方法是,不保证第二个参数的默认值。根据相应的.cpp文件的实现方式,默认值可能会更改。
在函数原型中,默认参数通常必须与第一个出现的函数名一起指定。如果由于函数定义也用作原型而省略了函数原型,则应在函数头中指定默认参数。