class Node
{
public:
Node *parent; // used during the search to record the parent of successor nodes
Node *child; // used after the search for the application to view the search in reverse
float g; // cost of this node + it's predecessors
float h; // heuristic estimate of distance to goal
float f; // sum of cumulative cost of predecessors and self and heuristic
Node() :
parent( 0 ),
child( 0 ),
g( 0.0f ),
h( 0.0f ),
f( 0.0f )
{
}
UserState m_UserState;
};
为什么我们应该使用构造函数
Node() :
parent( 0 ),
child( 0 ),
g( 0.0f ),
h( 0.0f ),
f( 0.0f )
{
}
而不是
Node()
{
parent = null;
child = null;
g = 0.0f;
h = 0.0f;
f = 0.0f;
}
谢谢:)
答案 0 :(得分:14)
对于普通旧数据(POD),这没什么好处,但是一旦你开始使用引用或编写类,它就会有所不同:
class Foo {
Bar bar;
public:
// construct bar from x
Foo(int x) : bar(x) { }
};
与
Foo::Foo(int x)
{
// bar is default-constructed; how do we "re-construct" it from x?
bar = x; // requires operator=(int) on bar; even if that's available,
// time is wasted default-constructing bar
}
有时,一旦构造了对象,你甚至都无法“重构”它,因为一个类可能不支持setter或operator=
。 const
成员当然不能“重构”或重置:
class FooWithConstBar {
const Bar bar;
public:
Foo(int x) {
// bar is cast in stone for the lifetime of this Foo object
}
};
修改:感谢@Vitus指出引用问题。
答案 1 :(得分:6)
由于某些情况下您实际上需要或出于性能原因,应使用初始化列表初始化成员,因此您应该一致并且总是使用它。
需要使用初始化列表的示例是当聚合没有默认构造函数或者有const成员时(是,非常见但允许)。
当应(但不强制)使用初始化列表时,如果您有一个聚合对象并且以下几点有效,那么
现在 - 你为什么不用它?
答案 2 :(得分:3)
答案 3 :(得分:2)
主要是因为性能问题。
讨论了here。
答案 4 :(得分:1)
主要原因是对象有效性和类不变量。另一个原因是易于使用。
如果您将所有内容放在构造函数中,那么当构造函数完成时,您将获得有效的节点。 如果你必须分别设置所有的实例变量,那么就有可能让一个节点包含一些未初始化的变量,因为程序员忘了或者其中一个赋值会抛出异常。后者不会发生在您的情况下,但一般情况下可能会发生。如果节点未完全初始化,则无法保证其行为符合您的预期。