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

时间:2016-09-01 09:38:19

标签: c++ compiler-errors compiler-warnings

我使用的是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();
    
  4. 对于前两种方法,我的编译器正在为成员提供"缺少初始化程序"警告。

    第三种方法在没有警告的情况下编译。

    • 这是一个有效的C ++语句吗?
    • 使用方法3我错过了一些真正的警告/错误吗?
    • 除了memset()之外,还有其他更好的替代方法吗?

1 个答案:

答案 0 :(得分:1)

首选方法应为:

之一
structName structVar{};
structName structVar = {};
auto structName = structVar{};

存在细微的差异,但不会像示例

中的聚合那样

这样做的另一个好处是,它为 structVar任何类型初始化structName,或者如果它无法执行初始化,则会导致程序格式错误(代码不对“编译”(加上它不允许缩小)。

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

C++14 draft standard:

  

§8.5.1聚合[dcl.init.aggr]

     

(1)聚合是一个没有用户提供的数组或类(第9条)   构造函数(12.1),没有私有或受保护的非静态数据成员   (第11条),没有基类(第10条),也没有虚函数   (10.3)

我使用的初始化语法称为List-initialization:

  

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

     

(1)列表初始化是   从braced-init-list初始化对象或引用。   [...]初始化列表可能为空。 [...]

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

  

§8.5.1聚合[dcl.init.aggr]

     

(2)当初始化列表初始化聚合时,如   在8.5.4中指定,初始化列表的元素被视为   增加下标的聚合成员的初始化程序   或会员订单。每个成员都是从中复制初始化的   相应的初始化子句

     

(7)如果列表中的初始化子句子数少于   聚合中的成员,然后每个成员未明确初始化   应从其支撑或等于初始化器初始化,或者如果有的话   从空的初始化列表中不是大括号或大小写的   (8.5.4)。

     

[例如:

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

将ss.a初始化为1,ss.b使用“asdf”,ss.c初始化,值为an   表达式为 int {}(即0),ss.d为值   of ss.b [ss.a](即's')

     

[...]

     

结束例子]

因此所有这些都是有效的,并做同样的事情:

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

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

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

struct structName structVar

使用:

structName structVar