默认成员值最佳实践

Pau*_*aul 64 c++ constructor default-value header-files c++11

编写C++ 11代码以在类的头文件中为类成员设置默认值时,这是一种好习惯吗?

或者在类的构造函数中执行此操作更好?

编辑:

我的意思是:

foo.h:

#include <string>

using std::string;

class Foo{
    private:
        string greet = "hello";
    public:
        Foo();
};
Run Code Online (Sandbox Code Playgroud)

VS

foo.cpp(当然有必要的头文件,但没有类内初始化):

Foo::Foo(){
    greet = "hello";
}
Run Code Online (Sandbox Code Playgroud)

哪一个更好,为什么?

Ker*_* SB 81

如果始终使用相同的初始值初始化类成员,则应该使初始化器内联,以避免重复.如果初始值取决于构造函数,则将其放在构造函数初始化列表中.(永远不要像你那样使用任务.)

例:

class Foo
{
    bool done = false;   // always start like this
    int qty;
    Bar * p;

public:
    Foo()                        : qty(0),              p(nullptr)    { }
    Foo(int q, Bar * bp)         : qty(q),              p(bp)         { }
    explicit Foo(char const * s) : qty(std::strlen(s)), p(new Bar(s)) { }

    // ...
};
Run Code Online (Sandbox Code Playgroud)

在这个假设的例子中,成员done总是需要以as开头false,所以最好是内联编写初始化器.其他两位成员,qty并且p,可以不同在三个不同的构造函数初始化,所以他们的建设者的初始化列表中初始化.

一个curiosum:请注意,提供内联初始值设定项可以防止您的类具有一个简单的默认构造函数.

  • "永远不要像你那样使用任务." 我认为解释为什么一个人永远不应该这样做将是你的答案的一个很好的补充. (9认同)
  • 您还可以使用构造函数委派来避免冗余. (7认同)
  • @cp.engr:因为你通常应该初始化,而不是重新分配。 (2认同)
  • @KerrekSB Paul 使用的作业与您使用的作业有什么区别?两者都将成员变量分配给一个值。 (2认同)
  • @KerrekSB 在你的示例的第 3 行,完成“done = false”算作作业吗? (2认同)

Mar*_*tin 12

这取决于您是否需要与旧的C++编译器保持兼容.当您不使用C++ 11时,您必须在构造函数中初始化大多数成员(所有非静态成员).此外,许多人主张明确初始化每个成员,即使这意味着明确地调用默认的ctor.通常,您应该将实现细节放在cpp文件中而不是头文件中,因此可以使用一个示例

Example:
//foo.h

class Foo{
public: 
  Foo();
private:
  std::vector<int> vect;
};

//foo.cpp

Foo::Foo():vect(){
}
Run Code Online (Sandbox Code Playgroud)

在C++ 11中,你有更多的选择,在类成员初始化程序将变得非常方便,特别是如果你有几个cors.以下是更多信息的良好链接:http://www.stroustrup.com/C++11FAQ.html#member-init

编辑后:根据您的代码,您使用的是C++ 11.据我所知,关于新可能性的良好实践的信息很少,但IMHO在类成员初始化器中非常方便将初始化集中在一个地方,这降低了复杂性和打字


Chr*_*bek 5

在标头中初始化的主要优点是使代码更加本地化且易于理解。它还可以节省一些打字时间。

在我看来,主要缺点是需要包含更多标头才能访问构造函数。简单的前向声明是不够的,这会使编译时间更长。