Как я могу использовать список инициализации членов для инициализации массива?

class A {
public:
   A();

private:
   char a[5];
   int* ptr;
};

A::A() : a(0), ptr(0) { }

Правильно ли это?

Ответ 1

Единственная разумная вещь, которую вы можете сделать с C-массивом в С++ 03, это инициализировать значение-инициализацию (в С++ 11 и за ее пределами можно инициализировать список).

Из стандарта С++ 03, §8.5/7:

Объект, инициализатор которого представляет собой пустой набор скобок, т.е.(), должен инициализироваться значением.

И из § 8.5/5:

Для инициализации объекта с типом T означает:

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

Для нулевой инициализации объекта типа T означает:

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

Итак, если ваше определение конструктора изменено на

A::A() : a(), ptr() { }

тогда вам гарантируется, что пост-построение, все 5 элементов A::a будут иметь значение '\0' и A::ptr будет null.

Ответ 2

Не боится; С++ не поддерживает инициализирующие массивы, подобные этому.

Вам просто нужно назначить его членам в тело конструктора A, или вы можете использовать инициализацию значения, если вам все равно, каковы значения:

struct A {
   int x[5];
   A() : x();
};

С++ 0x позволяет вам указывать все значения:

struct A {
   int x[5];
   A() : x{1,2,3,4,5} {}
};

Обратите внимание, что, поскольку массивы не являются class-object s, вы не сможете это сделать:

struct A {
   int x[5];
   A(std::initializer_list<int[5]>& i) // or whatever the T should be
      : x{i} // or x(i)
        {}
}
A a({1,2,3,4,5)};