我应该使用初始化列表还是在我的 C++ 中执行分配?构造函数?

发布于 2024-11-02 09:10:56 字数 947 浏览 5 评论 0原文

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;
    }

谢谢:)

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;
};

Why we should use the constructor

    Node() :
            parent( 0 ),
            child( 0 ),
            g( 0.0f ),
            h( 0.0f ),
            f( 0.0f )
    {
    }

instead of

    Node()
    {
        parent = null;
        child = null;
        g = 0.0f;
        h = 0.0f;
        f = 0.0f;
    }

Thanks :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

初懵 2024-11-09 09:10:56

对于普通的旧数据(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 指出了引用的问题。

For plain old data (POD), this has little benefit, but once you start either using references or composing classes it makes a difference:

class Foo {
    Bar bar;

  public:
    // construct bar from x
    Foo(int x) : bar(x) { }
};

versus

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
}

Sometimes, you won't even have a way of "re-constructing" an object once it has been constructed, as a class may not support setters or operator=. const members can certainly not be "re-constructed" or reset:

class FooWithConstBar {
    const Bar bar;

  public:
    Foo(int x) {
        // bar is cast in stone for the lifetime of this Foo object
    }
};

Edit: thanks to @Vitus for pointing out the problem with references.

初见终念 2024-11-09 09:10:56

由于在某些情况下您实际上需要或由于性能原因应该使用初始化列表来初始化成员,因此您应该一致并始终使用它。

需要使用初始化列表的示例是聚合没有默认构造函数或具有 const 成员(是的,不常见,但允许)。

例如,当您应该(但不强制)使用初始化列表时,您有一个聚合对象,并且以下几点有效:

  • 聚合有一个默认构造函数。
  • 您需要使用非默认值设置对象。
  • 聚合有一个构造函数,允许您设置所需的非默认值。

那么现在 - 为什么你不应该使用它呢?

As there are some circumstances where you actually need or by performance reasons should initialize members using an initialization list, you should be consistent and always use it.

Examples where you need to use initialization lists is when an aggregate has no default constructor or when you have const members (yes, uncommon, but allowed).

An example where when you should (but aren't forced to) use initialization lists is when you have an aggregate object and the following points are valid:

  • The aggregate has a default constructor.
  • You need to setup the object with non-default values.
  • The aggregate has a constructor that allows you to set the desired non-default values.

Now then - why should you not use it?

﹏半生如梦愿梦如真 2024-11-09 09:10:56

主要是因为性能问题。

此处对此进行了讨论。

Mainly because of performance issues.

It's discussed here.

千柳 2024-11-09 09:10:56

主要原因是对象有效性和类不变量。另一个原因是易于使用。

如果您将所有内容都放入构造函数中,那么当构造函数完成时,您将保证得到一个有效的 Node.js 文件。
如果必须单独设置所有实例变量,则可能会出现一个 Node 中的某些变量未初始化的情况,原因可能是程序员忘记了,或者某个赋值引发了异常。后者不会发生在你的情况下,但一般来说它可能会发生。如果节点未完全初始化,则无法保证其行为符合您的预期。

The main reason is object validity and class invariants. Another reason is ease of use.

If you put everything in the constructor then when the constructor finishes you are guaranteed a valid Node.
If you had to set all the instance variables separately then it would be possible to have a Node with some of the variables uninitialised either because the programmer forgot or if one of the assignments throws an exception. The latter would not occur in your case but in general it could. If the Node is not fully initialised its behaviour cannot be guaranteed to be as you expect.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文