【问题标题】:How to initialize structure in C++?如何在 C++ 中初始化结构?
【发布时间】:2016-09-01 09:38:18
【问题描述】:

我正在使用没有任何构造函数的 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();
    

对于前两种方法,我的编译器给出“缺少成员初始化程序”警告。

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

  • 它是有效的 C++ 语句吗?
  • 使用方法 3 是否遗漏了一些真正的警告/错误?
  • 除了memset()还有什么更好的替代方法吗?

【问题讨论】:

  • @101010 不,不一定。 struct foo { foo()=default; foo(int){} };.
  • 你的结构是什么样的?它有构造函数吗?析构函数?
  • 在 C++ 中你根本不需要在那里写struct,所以我想知道你“在互联网上搜索”时发现了什么资源。更喜欢从一本好书学习 C++...
  • @lightness-races-in-orbit,好的,我可以删除“结构”。但我对初始化更感兴趣。
  • Works fine for me。请创建一个Minimal, Complete, and Verifiable Example 并向我们展示。

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


【解决方案1】:

首选方法应该是以下之一:

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

有细微的差别,但不是你的例子中的聚合

这有一个额外的好处,它为structName 的任何类型 初始化structVar,或者如果它无法执行初始化,它会使程序格式错误(代码无法编译) (而且它不允许缩小)。

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

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) 列表初始化是 从花括号初始化列表初始化对象或引用。 [...]初始化列表可能为空。 [...]

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

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

用 1 初始化 ss.a,用“asdf”初始化 ss.b,用 an 的值初始化 ss.c int{}(即 0) 形式的表达式,以及带有值的 ss.d ss.b[ss.a]的(即's')

[...]

结束示例]

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

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

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


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

struct structName structVar

与:

structName structVar

【讨论】:

    猜你喜欢
    • 2021-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-22
    相关资源
    最近更新 更多