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のコンストラクターを作成する必要があります。

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では、統一された初期化リストを使用できますが、それでもFooにはdtorが必要です。

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(としてBar() : foo(), x(8) { })、Fooにデフォルトのコンストラクターを与える必要があります。

于 2010-11-17T09:25:31.277 に答える