如何在C++中初始化结构?

How to initialize structure in C++?

我正在使用没有任何构造函数的 C 风格结构,如下所示:

struct structName {
    int  mem1;
    int  mem2;
    char mem3;
    char mem4;
}

我正在创建这个结构的一个变量,我想将这个结构的所有成员初始化为零。我找到了以下方法。

  1. struct structName structVar = {};
    
  2. struct structName structVar = {0};
    
  3. struct structName structVar = struct structName();
    

对于前两种方法,我的编译器给出了 "missing initializer for member" 警告。

第三种方法编译时没有警告。

首选方法应为以下方法之一:

structName structVar{};
structName structVar = {};
auto structName = structVar{};

存在细微差别,但不是像您示例中的聚合那样

这有一个额外的好处,它为 structName 任何类型 初始化 structVar,或者如果它不能执行初始化,它会使程序出错-形成(代码不编译)(加上它不允许缩小)。

在您的具体示例中,structName 是一个聚合:

C++14 draft standard:

§8.5.1 Aggregates [dcl.init.aggr]

(1) An aggregate is an array or a class (Clause 9) with no user-provided constructors (12.1), no private or protected non-static data members (Clause 11), no base classes (Clause 10), and no virtual functions (10.3)

我使用的初始化语法称为列表初始化:

§8.5.4 List-initialization [dcl.init.list]

(1) List-initialization is initialization of an object or reference from a braced-init-list. [...] An initializer list may be empty. [...]

对于我们的聚合,这意味着:

§8.5.1 Aggregates [dcl.init.aggr]

(2) When an aggregate is initialized by an initializer list, as specified in 8.5.4, the elements of the initializer list are taken as initializers for the members of the aggregate, in increasing subscript or member order. Each member is copy-initialized from the corresponding initializer-clause

(7) If there are fewer initializer-clauses in the list than there are members in the aggregate, then each member not explicitly initialized shall be initialized from its brace-or-equal-initializer or, if there is no brace-or-equalinitializer, from an empty initializer list (8.5.4).

[ Example:

struct S { int a; const char* b; int c; int d = b[a]; };
S ss = { 1, "asdf" };

initializes ss.a with 1, ss.b with "asdf", ss.c with the value of an expression of the form int{} (that is, 0), and ss.d with the value of ss.b[ss.a] (that is, ’s’)

[...]

end example ]

所以所有这些都是有效的并且做完全相同的事情:

structName structVar = {};
structName structVar = {0};
structName structVar = {0, 0};

但是,如果聚合中至少有一个 initializer-clauses 且少于成员数,则 gccclang 会发出警告。可能是您打算初始化所有成员,但遗漏了一些。所以空的初始化列表是最安全的选择。


作为旁注,struct 不是必需的,并且通常不在声明中使用。所以替换这个:

struct structName structVar

与:

structName structVar