编写C ++ 11代码以在类头文件中为类成员设置默认值时,这是不错的做法?
或者在类的构造函数中执行此操作会更好吗?
编辑:
我的意思是:
foo.h中:
#include <string>
using std::string;
class Foo{
private:
string greet = "hello";
public:
Foo();
};
VS
foo.cpp (当然有必要的头文件,但没有进行类内初始化):
Foo::Foo(){
greet = "hello";
}
哪一个更好,为什么?
答案 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
开头,因此最好将内置初始化程序编写。另外两个成员qty
和p
可以在三个不同的构造函数中的每一个中进行不同的初始化,因此它们在构造函数的初始化列表中初始化。
一个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)
在标头中初始化具有使代码更加本地化且易于理解的主要优点。它还节省了一些打字。
在我看来,主要的缺点是需要包含更多标头才能访问构造函数。简单的前向声明是不够的,因为编译需要更长的时间。