【问题标题】:Will the compiler generated default constructor initialize the pointers in std::array to nullptr?编译器生成的默认构造函数是否会将 std::array 中的指针初始化为 nullptr?
【发布时间】:2019-09-16 21:57:49
【问题描述】:

给出下面的代码是否正确,编译器应该生成Node(),它应该调用std::array<Node *, 100>(),它应该初始化所有100个指向nullptr的指针。

旁注:我知道如果我使用std::array<Node *, 100> children {};,我可以做到这一点,但我不想让我的代码工作(它已经工作了),我想确保它不会意外工作.

struct Node
{
    int value;
    std::array<Node *, 100> children;
}

更新:

这里的指针是垃圾:

struct Node
{
    int value;
    std::array<Node *, 100> children;
}

struct Node
{
    Node() : children() {}
    int value;
    std::array<Node *, 100> children;
}

这里的指针是 nullptr:

struct Node
{
    int value;
    std::array<Node *, 100> children {};
}

struct Node
{
    Node() : children{} {}
    int value;
    std::array<Node *, 100> children;
}

如果我错了,请纠正我。

【问题讨论】:

  • 你想要的是使用shared_ptr&lt;Node *&gt; 而不是裸指针。只要您在任何地方(始终如一地)使用它们,最终的惊喜就会减少。

标签: c++ arrays initialization std


【解决方案1】:

std::array的构造函数上引用cppreference

按照聚合初始化规则初始化数组 (请注意,默认初始化可能会导致不确定的值 对于非 T 级)

通过像std::array&lt;Node *, 100&gt; children; 这样声明变量,您可以调用默认构造函数。而且,根据初始化规则,POD(intchardouble,指针,...)没有默认初始化。所以不,如果你不使用聚合初始化,你的数组将不会被 nullptr 初始化。

聚合初始化

std::array<Node *, 100> children;

调用默认构造函数,但没有给出聚合初始化器,因此聚合初始化不会发生。不过

std::array<Node *, 100> children{}
std::array<Node *, 100> children = {};

不仅调用默认构造函数,还执行聚合初始化。在这种情况下,聚合 {} 只是空的。并且,按照聚合初始化的规则,如果初始化器的数量少于数据成员,则每个未初始化的成员都将被默认初始化。所以

Node x;
std::array<Node *, 100> children = {&x};

例如,将使用指向x 的指针初始化第一个数组元素,并且每个后续元素将默认初始化为nullptr

【讨论】:

  • 我要补充说明:不,数组不会用 nullptr 初始化如果 Node 是默认初始化的
  • 一些术语在我身上丢失了...std::array&lt;Node *, 100&gt; children {}; 将根据此初始化所有 100 个指向 nullptr 的指针:stackoverflow.com/questions/35849693/… 这是否意味着 Node() : children() {} 不会这样做,但是Node() : children{} {} 会吗?
  • 太棒了,现在很干净。谢谢!
【解决方案2】:

根据this answerstd::array 指针的默认初始化将初始化它包含的指针,它们的值将是不确定的。

std::array<Node *, 100> children; // pointers are uninitialized

但是,您可以使用 value 初始化来初始化所有包含的指向 nullptr 的指针。在std::array 上,这具有对数组中的每个值进行值初始化的效果,进而对每个指针进行零初始化。

std::array<Node *, 100> children {}; // pointers are all null

在成员初始化器列表中,您也可以这样做:

Node::Node() : children{/* value init array */} {/* empty c'tor body */}

【讨论】:

    【解决方案3】:

    在指针被赋值之前,它默认指向一个“垃圾”地址。编译器不会为它们分配默认值nullptr。事实上,它并没有为指针分配任何“默认”值。
    编辑:
    来自 cppreference documentation for std::array

    请注意,默认初始化可能会导致非类 T 的值不确定

    所以如果使用默认构造函数,需要自己给每个元素赋值nullptr

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-01-12
      • 2011-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-16
      相关资源
      最近更新 更多