52

我在 C++ 中有以下类定义:

struct Foo {
  int x;
  char array[24];
  short* y;
};

class Bar {
  Bar();

  int x;
  Foo foo;
};

并希望在 Bar 类的初始化程序中将“foo”结构(及其所有成员)初始化为零。可以这样做吗:

Bar::Bar()
  : foo(),
    x(8) {
}

... ?

或者foo(x)在初始化列表中到底做了什么?

或者该结构是否甚至从编译器自动初始化为零?

4

2 回答 2

54

首先,您应该(必须!)阅读有关 POD 和聚合的c++ 常见问题解答。在您的情况下,Foo确实是一个 POD 类并且foo()是一个值初始化

对 T 类型的对象进行值初始化意味着:

  • 如果 T 是具有用户声明的构造函数 (12.1) 的类类型(第 9 条),则
    调用 T 的默认构造函数(如果 T 没有可访问的默认构造函数,则初始化是错误的);
  • 如果 T 是没有用户声明的构造函数的非联合类类型,则 T 的每个非静态数据成员和基类组件都是值初始化的;
  • 如果 T 是一个数组类型,那么每个元素都是值初始化的;
  • 否则,对象被零初始化

所以是的, foo 将被零初始化。请注意,如果您从Bar构造函数中删除了此初始化,则foo只会默认初始化

如果没有为对象指定初始化程序,并且该对象是(可能是 cv 限定的)非 POD 类类型(或其数组),则该对象应默认初始化;如果对象是 const 限定类型,则基础类类型应具有用户声明的默认构造函数。 否则,如果没有为非静态对象指定初始化器,则该对象及其子对象(如果有)具有不确定的初始值

于 2010-11-17T09:42:29.880 回答
10

在标准 C++ 中,您需要为 Foo 创建一个 ctor。

struct Foo {

  Foo(int const a, std::initializer_list<char> const b, short* c)
    : x(a), y(c) {
    assert(b.size() >= 24, "err");
    std::copy(b.begin(), b.begin() + 24, array);
  }

  ~Foo() { delete y; }

  int x;
  char array[24];
  short* y;
};

class Bar {

  Bar() : x(5), foo(5, {'a', 'b', ..., 'y', 'z'},
    new short(5)) { }

  private:

  int x;
  Foo foo;
};

在 C++0x 中,您可以使用统一初始化列表,但您仍然需要 dtor 来表示 Foo:

class Bar {

  Bar() : x(5), foo{5, new char[24]{'a', 'b', ..., 'y', 'z'},
    new short(5)} { }
  ~Bar() { delete[] foo.array; delete foo.y;}
  }
  private:

  int x;
  Foo foo;
};

要默认初始化foo(as Bar() : foo(), x(8) { }),您需要给 Foo 一个默认 ctor。

于 2010-11-17T09:25:31.277 回答