关于c ++:函数参数的默认值

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)
{

}

这是一个标准的工作方式,和为什么?


如果将声明放在头文件中,定义放在单独的.cpp文件中,而#include头文件来自不同的.cpp文件,则可以看到不同之处。

具体来说,假设:

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);
}

test.cpp的编译将看不到默认参数声明,并将失败并出现错误。

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

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文件的实现方式,默认值可能会更改。


    在函数原型中,默认参数通常必须与第一个出现的函数名一起指定。如果由于函数定义也用作原型而省略了函数原型,则应在函数头中指定默认参数。