【问题标题】:What if the default parameter value is defined in code not visible at the call site?如果在调用站点不可见的代码中定义了默认参数值怎么办?
【发布时间】:2009-07-17 09:16:13
【问题描述】:

我发现了一些奇怪的代码...

//in file ClassA.h:
class ClassA {
public:
    void Enable( bool enable );
};

//in file ClassA.cpp
#include <ClassA.h>
void ClassA::Enable( bool enable = true )
{
   //implementation is irrelevant
}

//in Consumer.cpp
#include <ClassA.h>
....
ClassA classA;
classA.Enable( true );

显然,由于Consumer.cpp 只包含ClassA.h 而不是ClassA.cpp,编译器将无法看到该参数具有默认值。

方法实现的签名中声明的默认值ClassA::Enable什么时候会产生影响?仅当从包含ClassA.cpp 的文件中调用该方法时才会发生这种情况吗?

【问题讨论】:

    标签: c++ header


    【解决方案1】:

    默认值只是编译时的事情。编译代码中没有默认值之类的东西(没有元数据或类似的东西)。它基本上是“如果你不写任何东西,我会为你指定”的编译器替代品。因此,如果编译器看不到默认值,它会假定没有默认值

    演示:

    // test.h
    class Test { public: int testing(int input); };
    
    // main.cpp
    #include <iostream>
    // removing the default value here will cause an error in the call in `main`:
    class Test { public: int testing(int input = 42); };
    int f();
    int main() {
       Test t;
       std::cout << t.testing()  // 42
                 << " " << f()   // 1000
                 << std::endl;
       return 0;
    }
    
    // test.cpp
    #include "test.h"
    int Test::testing(int input = 1000) { return input; }
    int f() { Test t; return t.testing(); }
    

    测试:

    g++ main.cpp test.cpp
    ./a.out
    

    【讨论】:

      【解决方案2】:

      首先让我承认这是我第一次看到这种类型的代码。在头文件中放一个默认值IS是正常的做法,但这不是。

      我的猜测是,这个默认值只能用于写在同一个文件中的代码,这样写这个的程序员想把它放在某种容易调用函数的地方,但他不想打扰对外可见的接口(头文件)。

      【讨论】:

        【解决方案3】:

        这只会发生在方法 从文件中调用 包括 ClassA.cpp?

        没错。但请注意,这样做几乎肯定会产生多个定义错误,因此默认值仅在 ClassA.cpp 中的定义点才真正可用。

        【讨论】:

        • 这不是错误。仅当两个定义都提供默认值时才会产生错误。
        • 如果文件被多次#included,实际函数会导致多次定义错误,这就是我所指的。
        【解决方案4】:

        将默认值放在声明中,而不是定义中。

        class ClassA {
        public:
            void Enable( bool enable = true );
        };
        

        【讨论】:

        • 谁标记了这个??如果你标记我,请告诉我原因,以便我至少可以修复它。
        • 其实是我把它记下来了,原因是 OP 显然知道正确的方法是把它放在声明中而不是定义中。 OP想知道在定义中定义这样的东西有什么影响,而您没有彻底阅读问题就回答了。是的,很抱歉没有让你知道标记它的原因。我应该这样做的。
        • OP 没有提到将其放入声明中,所以我建议解决他提到的可见性问题?
        • OP 没有说或暗示他有能见度问题。他询问了一段特定代码的效果。如果有人发现此页面搜索有关如何指定默认参数的信息,IMO 这是一个很好的答案,但这不是问题的答案,也不太可能对 OP 有用。因此,它是否值得投赞成票或反对票,这超出了我的范围。 +0 :-)
        猜你喜欢
        • 1970-01-01
        • 2012-04-24
        • 2012-12-20
        • 2016-03-04
        • 2019-04-23
        • 2014-12-31
        • 2016-11-12
        • 1970-01-01
        • 2016-07-27
        相关资源
        最近更新 更多