默认成员值最佳实践

时间:2012-07-21 18:32:03

标签: c++ constructor c++11 header-files default-value

编写C ++ 11代码以在类头文件中为类成员设置默认值时,这是不错的做法?

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

编辑:

我的意思是:

foo.h中

#include <string>

using std::string;

class Foo{
    private:
        string greet = "hello";
    public:
        Foo();
};

VS

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

Foo::Foo(){
    greet = "hello";
}

哪一个更好,为什么?

3 个答案:

答案 0 :(得分:72)

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

示例:

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

    // ...
};

在此假设示例中,成员done始终需要以false开头,因此最好将内置初始化程序编写。另外两个成员qtyp可以在三个不同的构造函数中的每一个中进行不同的初始化,因此它们在构造函数的初始化列表中初始化。

一个curiosum:请注意,提供内联初始化程序会阻止您的类具有普通的默认构造函数

答案 1 :(得分:11)

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

Example:
//foo.h

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

//foo.cpp

Foo::Foo():vect(){
}

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

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

答案 2 :(得分:2)

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

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