Инициализация по умолчанию 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 = {};
инициализирует массив нулем даже для автоматического (локального) объекта.
Я считаю, что если вы не инициализируете его, когда объявляете, его можно установить на что угодно. Иногда это адрес или случайное значение.
Лучшей практикой является инициализация после объявления.