Подтвердить что ты не робот

Как инициализировать член-структуру в списке инициализаторов класса С++?

У меня есть следующие определения классов в С++:

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

class Bar {
  Bar();

  int x;
  Foo foo;
};

и хотел бы инициализировать структуру "foo" (со всеми ее членами) до нуля в инициализаторе класса Bar. Это можно сделать следующим образом:

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

...?

Или что именно делает foo (x) в списке инициализаторов?

Или структура, даже инициализированная автоматически до нуля от компилятора?

4b9b3361

Ответ 1

Прежде всего, вы должны (должны!) прочитать этот С++ faq относительно POD и агрегатов. В вашем случае Foo действительно является классом POD и foo() является инициализацией значения :

Чтобы инициализировать объект типа типа T означает:

  • если T - тип класса (раздел 9) с объявленным пользователем конструктором (12.1), тогда конструктор по умолчанию для T называется (и инициализация плохо сформирована, если T не имеет доступного конструктора по умолчанию);
  • если T - тип неединичного класса без конструктора, объявленного пользователем, то каждый нестатический элемент данных и компонент базового класса T инициализируются значением;
  • если T - тип массива, то каждый элемент инициализируется значением;
  • , иначе объект инициализируется нулем

Итак, да, foo будет нулевой инициализирован. Обратите внимание, что если вы удалили эту инициализацию из конструктора Bar, Foo будет только инициализирован по умолчанию:

Если для объект, и объект имеет (возможно, cv-квалифицированный) тип класса не-POD (или массив), объект должен быть по умолчанию инициализируется; если объект типа const, тип базового класса должен иметь объявленный пользователем конструктор по умолчанию. В противном случае, если инициализатор не установлен для нестатического объекта, объект и его подобъекты, если они есть, имеют неопределенный начальный Значение;

Ответ 2

В стандартном С++ вам нужно сделать ctor для 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;
};

В С++ 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 (как Bar() : foo(), x(8) { }) вам нужно указать Foo по умолчанию ctor.