为什么我们只需要在头文件中声明默认参数?

时间:2015-02-22 22:05:18

标签: c++

对于方法中的默认参数,我们只需要在头文件中声明它,我想知道为什么我们不需要在实现中指定它?

method1(int i,int j = 2)

2 个答案:

答案 0 :(得分:5)

因为默认参数是在调用者中处理的。编译器会根据标头自动添加缺少的参数。函数本身并不需要该信息,并且提供两次信息只会引起不一致。如果你想在实现中也有它,你可以将它放在注释中,但是你必须保持同步(例如method1(int i, int j /*=2*/)。作为替代,你可以提供两个重载,以便丢失参数由实现添加

method1(int i, int j);
method1(int i);

method1(int i, int j) { ... }
method1(int i) { method1(i, 2); }

这可能会略微降低性能,因为编译器可能无法内联1-arg调用,而它始终可以使用默认参数。

答案 1 :(得分:0)

参数的默认值应该提供调用者未提供的缺少参数。因此编译器必须在调用函数时添加它们。

此外,该标准明确预见到不同的默认值可以在不同的范围内使用:

  

8.3.6 / 4:(...)默认参数可以在同一范围内的函数的后续声明中添加。声明   不同的范围具有完全不同的默认参数集。   也就是说,内部作用域中的声明不会获取默认参数   来自外部范围的声明,反之亦然。在给定的功能中   声明,参数后面的每个参数都有一个默认值   参数应具有此前一个或前一个提供的默认参数   声明或应是功能参数包。

简而言之:在不同的范围(和编译单元)中,您可以使用不同的默认值集,但在任何给定的范围内,您都无法重新定义这些默认值。

一个例子来说明这一点:

void foo(int i = 10, int j = 20);    // declare default parameters 

void test()                          // entering a new scope 
{
    void foo(int i = 5, int j = 10);    // redeclared in scope of the test function
    cout << "Call foo within test(): ";
    foo();                             // called with the default values OF THE SCOPE: 5 10  
}

// void foo(int i = 8, int j = 20);    // FORBIDDEN ! can't redeclare  different parameters in global scope as it was already declared before

int main(int ac, char**av) 
{
    cout << "Call foo within main(): "; 
    foo();                      // called with the default value of global scope : 10 20 
    test(); 
}

void foo(int i, int j) {  // not allowed to redeclare defaults here
    cout << "FOO with " << i << " and " << j << endl; 
}

然而,请谨慎使用多次默认的这种可能性,因为出于实际原因,您通常只在一个标题中声明函数,如果您在多个地方重新声明,则会使整个内容更难维护。