Если все объекты имеют по крайней мере один конструктор, это по умолчанию c'tor, определяемый компилятором или пользователем, то как объекты могут быть неинициализированы.
Неинициализированные объекты существуют в С++?
Ответ 1
Можно объявлять объекты, на которых не выполняются инициализации. Эти объекты существуют, они имеют неопределенное значение, и использование этого значения - это поведение undefined (есть исключение из этого правила для символов).
Такой объект может быть создан по умолчанию. Это указано в стандарте С++ (§11.6 Инициализаторы) [dlc.init]:
Для инициализации объекта типа T по умолчанию:
(7.1) - Если T является классом класса (возможно, cv-qualit) (раздел 12), рассматриваются конструкторы. Применимое конструкторы перечислены (16.3.1.3), а лучший для инициализатора() выбирается посредством перегрузки резолюции (16.3). Выбранный таким образом конструктор вызывается с пустым списком аргументов для инициализации объект.
(7.2). Если T - тип массива, каждый элемент инициализируется по умолчанию.
(7.3) - В противном случае не выполняется инициализация.
Тем не менее, статические объекты всегда ноль-инициализируются. Таким образом, любой встроенный динамический или автоматический срок хранения не может быть инициализирован, даже если он является подзаголовком;
int i; //zero-initialized
struct A{
int i;
};
struct B
{
B(){};
B(int i)
:i{i}{}
int i;
int j;
};
A a; //a.i is zero-initialized
int main()
{
int j; //not initialized
int k{}; //zero-initialized
A b; //b.i not initialized
int* p = new int; //*p not initialized
A* q = new A; //q->i not initialized
B ab; //ab.i and ab.j not initialized
B ab2{1}; //ab.j not initialized
int xx[10]; //xx element not initialized.
int l = i; //OK l==0;
int m = j; //undefined behavior (because j is not initialized)
int n = b.i; //undefined behavior
int o = *p; //undefined behavior
int w = q->i; //undefined behavior
int ex = x[0] //undefined behavior
}
Для инициализации члена [class.base.init] может помочь:
В конструкторе без делегирования, если данный потенциально сконструированный подобъект не обозначается mem- Инициализатор-идентификатор (включая случай, когда нет mem-initializer-list, поскольку у конструктора нет ctor-инициализатор), то - если объект является нестатическим членом данных, у которого есть инициализатор элемента по умолчанию (12.2) и либо
(9.1.1) - класс конструкторов является объединением (12.3), и никакой другой вариант член этого союза не обозначен с помощью mem-initializer-id или
(9.1.2) - класс конструкторов не является объединением и, если сущность является членом анонимного объединения, no другой член этого союза обозначается идентификатором mem-initializer-id, объект инициализируется из его инициализатора элемента по умолчанию, как указано в 11.6;
(9.2) - в противном случае, если объект является анонимным объединением или вариантом (12.3.1), никакая инициализация не является выполняется;
(9.3) - в противном случае объект инициализируется по умолчанию (11.6)
Члены тривиального анонимного объединения также не могут быть инициализированы.
Также можно было спросить, может ли жизнь жизни объекта начинаться без какой-либо инициализации, например, используя reinterpret_cast. Ответ следующий: reinterpret_cast, создающий тривиальный конструктивный объект по умолчанию
Ответ 2
В стандарте не говорится о существовании объектов, однако существует понятие времен жизни объектов.
В частности, из [basic.life] †
Время жизни объекта типа
T
начинается, когда:
хранилище с правильным выравниванием и размером для типа
T
получено, аесли объект имеет непустую инициализацию, его инициализация завершена
С незапущенной инициализацией, определяемой как
Говорят, что объект имеет непустую инициализацию, если он относится к классу или aggregate type, и он или один из его подобъектов инициализируется конструктором, отличным от тривиального конструктора по умолчанию.
Мы можем заключить, что для объектов с пустыми инициализациями (например, int
s) их сроки жизни начинаются сразу же после их хранения, даже если они оставлены неинициализированными.
void foo()
{
int i; // i lifetime begins after this line, but i is uninitialized
// ...
}
† Добавлены ссылки для удобства чтения, они не отображаются в стандартном