142

1.

int Add (int a, int b = 3);
int Add (int a, int b)
{

}

2.

int Add (int a, int b);
int Add (int a, int b = 3)
{

}

两者都有效;这是标准方式,为什么

4

5 回答 5

213

如果您将声明放在头文件中,将定义放在单独的.cpp文件中,并且#include头文件来自不同的.cpp文件,您将能够看到差异。

具体来说,假设:

库文件

int Add(int a, int b);

库文件

int Add(int a, int b = 3) {
   ...
}

测试.cpp

#include "lib.h"

int main() {
    Add(4);
}

的编译test.cpp将看不到默认的参数声明,并且会因错误而失败。

因此,默认参数定义通常在函数声明中指定:

库文件

int Add(int a, int b = 3);
于 2010-05-16T07:38:32.480 回答
45

在 C++ 中,关于默认参数在参数列表中的位置的要求如下:

  1. 给定参数的默认参数必须指定不超过一次。多次指定它(即使使用相同的默认值)是非法的。

  2. 具有默认参数的参数必须在参数列表的末尾形成一个连续的组。

现在,请记住这一点,在 C++ 中,只要不断满足上述要求,就可以将具有默认参数的参数集从函数的一个声明“增长”到下一个。

例如,您可以声明一个没有默认参数的函数

void foo(int a, int b);

为了在声明后调用该函数,您必须明确指定两个参数。

稍后(进一步向下)在同一个翻译单元中,您可以再次重新声明它,但这次使用一个默认参数

void foo(int a, int b = 5);

从这一点开始,你可以只用一个明确的参数来调用它。

再往下,您可以再次重新声明它,再添加一个默认参数

void foo(int a = 1, int b);

从这一点开始,您可以在没有显式参数的情况下调用它。

完整的示例可能如下所示

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)
{
  // ...
}

至于您问题中的代码,这两种变体都是完全有效的,但它们的含义不同。第一个变体立即为第二个参数声明一个默认参数。第二个变体最初声明你的函数没有默认参数,然后为第二个参数添加一个。

您的两个声明的最终效果(即第二个声明之后的代码所看到的方式)完全相同:该函数的第二个参数具有默认参数。但是,如果您设法在第一个和第二个声明之间压缩一些代码,这两个变体的行为会有所不同。在第二个变体中,函数在声明之间没有默认参数,因此您必须明确指定两个参数。

于 2010-05-16T07:49:21.223 回答
5

第一种方式优于第二种方式。

这是因为头文件会显示该参数是可选的以及它的默认值是什么。此外,这将确保默认值相同,无论对应的 .cpp 文件的实现如何。

在第二种方式中,不能保证第二个参数的默认值。默认值可能会更改,具体取决于相应 .cpp 文件的实现方式。

于 2010-05-16T07:43:42.547 回答
4

默认参数必须在函数名的第一次出现时指定——通常在函数原型中。如果因为函数定义也用作原型而省略了函数原型,则应在函数头中指定默认参数。

于 2010-05-16T07:40:09.337 回答
0

这里要记住的是,默认参数必须是函数定义中的最后一个参数。

以下代码将无法编译:

void fun(int first, int second = 10, int third);

以下代码将编译:

void fun(int first, int second, int third = 10);
于 2020-12-05T00:36:16.857 回答