简体   繁体   English

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

[英]How to initialize structure in C++?

I am using a C-style structure which does not have any constructor, like this: 我正在使用没有任何构造函数的C样式结构,如下所示:

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

I am creating a variable of this structure and I want to initialize all members of the structure to zero. 我正在创建此结构的变量,并且希望将结构的所有成员初始化为零。 I found the following methods. 我发现以下方法。

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

For the first two methods, my compiler is giving "missing initializer for member" warning. 对于前两种方法,我的编译器给出了“缺少成员的初始化器”警告。

The third approach compiles without warnings. 第三种方法无需警告即可编译。

  • Is it a valid C++ statement? 它是有效的C ++语句吗?
  • Am I missing some genuine warning/error by using method 3? 我是否使用方法3错过了一些真正的警告/错误?
  • Is there any better alternative method, apart from memset()? 除了memset()之外,还有其他更好的方法吗?

The preferred method should be one of: 首选方法应为以下之一:

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

there are subtle differences, but not for aggregates as in your example 有细微的差别,但不是像您的示例中的聚合

This has the added advantage that it initializes structVar for any type of structName or if it cannot perform an initialization it makes the program ill-formed (the code doesn't compile) (plus it doesn't allow narrowing). 这样做还有一个好处,就是它structVar任何类型structName初始化structVar ,或者如果它不能执行初始化,则会使程序structName (代码无法编译)(而且不允许缩小)。

In your specific example, structName is an agregate: 在您的特定示例中, structName是一个聚合:

C++14 draft standard: C ++ 14标准草案:

§8.5.1 Aggregates [dcl.init.aggr] §8.5.1聚合[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) (1)集合是没有用户提供的构造函数(12.1),没有私有或受保护的非静态数据成员(第11章),没有基类(第10章)且没有虚拟的数组或类(第9章)功能(10.3)

The initialization syntax I used is called List-initialization: 我使用的初始化语法称为List-initialization:

§8.5.4 List-initialization [dcl.init.list] §8.5.4列表初始化[dcl.init.list]

(1) List-initialization is initialization of an object or reference from a braced-init-list. (1)列表初始化是从括号初始化列表初始化对象或引用。 [...] An initializer list may be empty. [...]初始化程序列表可能为空。 [...] [...]

For our aggregate this means: 对于我们而言,这意味着:

§8.5.1 Aggregates [dcl.init.aggr] §8.5.1聚合[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. (2)当聚合由初始化器列表初始化时(如8.5.4中所述),初始化器列表中的元素被用作聚合成员的初始化器(按递增的下标或成员顺序)。 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). (7)如果列表中的初始化子句少于聚合中的成员,则每个未显式初始化的成员都应从其brace-or-equal-initializer进行初始化,或者,如果没有brace-or-equalinitializer,则进行初始化。 ,从一个空的初始化程序列表(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') 用1初始化ss.a,用“ asdf”初始化ss.b,用int {}形式的表达式的值(即0)初始化ss.c,用ss.b [ss]的值初始化ss.d。 .a](即“ s”)

[...] [...]

end example ] 结束示例]

So all of these are valid and do the exact same thing: 因此,所有这些都是有效的,并且做的完全相同:

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

However if there is at least one initializer-clauses and less than there are members in the aggregate, gcc and clang emit a warning. 但是,如果至少有一个initializer-clauses并且聚合中initializer-clauses少于成员,则gccclang会发出警告。 It might be that you intended to initialize all members, but missed some. 您可能打算初始化所有成员,但是错过了一些成员。 So the empty initializer list is the safest choice. 因此,空的初始化程序列表是最安全的选择。


As a side note struct is not needed and universally not used in a declaration. 附带说明一下,不需要使用struct ,并且在声明中通常不使用该结构。 So replace this: 因此,替换为:

struct structName structVar

with: 与:

structName structVar

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM