Инициализация по умолчанию C++ массивов-членов?

Это простой вопрос, но я не могу найти окончательного ответа.

Если у нас есть следующий класс:

class Test
{
...
  char testArray[10];

...
}; 

Когда мы создаем экземпляр Test, каково значение по умолчанию testArray[1]?

Если бы это был локальный массив, он был бы неинициализирован.
Если бы это был статический массив, он был бы инициализирован в 0.

Что он делает, когда массив является членом класса?

3 ответа

Решение

Из стандарта, раздел 8.5 [dcl.init]:

По умолчанию инициализировать объект типа T средства:

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

  • если T тип массива, каждый элемент инициализируется по умолчанию;

  • в противном случае инициализация не выполняется.

также раздел 12.6.2 [class.base.init]:

В не делегирующем конструкторе, если заданный нестатический элемент данных или базовый класс не обозначен с помощью mem-initializer-id (включая случай, когда нет mem-initializer-list, потому что конструктор не имеет ctor-initializer) и сущность не является виртуальным базовым классом абстрактного класса (10.4), то

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

Так как тип элемента char когда каждый элемент инициализируется по умолчанию, инициализация не выполняется. Содержимое оставлено с произвольными значениями.

Если, конечно, это не член экземпляра класса, а экземпляр имеет статическую продолжительность хранения. Затем весь экземпляр инициализируется нулями, членами массива и всем до начала выполнения.

Это зависит от факторов, которые вы забыли упомянуть.

Если твой Test не имеет пользовательского конструктора или ваш пользовательский конструктор не предпринимает усилий для инициализации массива, и вы объявляете объект типа Test как

Test test; // no initializer supplied

тогда он будет вести себя точно так же, как вы описали выше. Для автоматического (локального) объекта содержимое массива останется непредсказуемым. Для статического объекта содержимое гарантированно будет равно нулю.

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

Если ваш класс является агрегатом, то содержимое может зависеть от агрегатного инициализатора, который вы указали в объявлении объекта. Например

Test test = {};

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

Я считаю, что если вы не инициализируете его, когда объявляете, его можно установить на что угодно. Иногда это адрес или случайное значение.

Лучшей практикой является инициализация после объявления.

Другие вопросы по тегам