Вот основная идея.И A a2{};
, и B b2{};
будут выполнять то, что называется " инициализация значения " для двух объектов.Однако способ инициализации значения зависит от того, как определены эти типы.
B
- это объект, который имеет предоставленный пользователем конструктор по умолчанию.«Предоставленный пользователем» - это термин, обозначающий, когда вы предоставляете тело для конструктора по умолчанию.Из-за этого при инициализации значения будет вызываться конструктор по умолчанию.Этот конструктор по умолчанию не инициализирует его члены, поэтому члены остаются неинициализированными.
A
- это объект, который не имеет предоставленного пользователем конструктора по умолчанию.Также у него нет других пользовательских конструкторов.И конструктор по умолчанию тоже не удаляется.И в A
нет инициализаторов элементов по умолчанию.Учитывая все это, инициализация значения будет выполнять нулевую инициализацию для объекта.Это означает, что он запишет все нули в память для этого объекта до того, как он появится.
Так говорят правила;два не ведут себя одинаково, и при этом они не предназначены.Также вы ничего не можете сделать, чтобы пользовательский конструктор по умолчанию действовал как конструктор по умолчанию в во всех случаях.Вы можете сделать так, чтобы значение предоставленного пользователем конструктора инициализировало его члены, но это будет происходить постоянно, даже если вы используете инициализацию по умолчанию (например, B b1;
).
Почему правила говорят это?Потому что = default
- это , который не должен быть эквивалентным пустому телу конструктора.В самом деле, отличия - вот почему = default
существует как элемент.
Когда вы = default
используете конструктор по умолчанию, вы говорите «сгенерируйте конструктор по умолчанию, как обычно».Это важно, потому что есть вещи, которые вы можете сделать, которые активно мешают компилятору генерировать конструктор по умолчанию для вас.Если вы укажете другие конструкторы (которые не являются конструкторами копирования / перемещения), компилятор не сгенерирует их автоматически.Таким образом, используя синтаксис = default
, вы сообщаете компилятору, что вам нужен сгенерированный конструктор по умолчанию.
Напротив, если вы создаете пустое тело в конструкторе по умолчанию, вы говорите что-то совершенно другое.Вы явно говорите: «Если пользователь вызывает мой конструктор по умолчанию, я хочу, чтобы мои члены инициализировались по умолчанию».Вот что это значит, когда у вас есть пустой список инициализатора члена в конструкторе, в конце концов.Вот что он должен делать.
Если бы = default
и пустое тело вели себя одинаково, у вас не было бы способа получить такое поведение, сказать, что вы хотите инициализацию ваших членов по умолчанию независимо от того, что.
По сути, утверждение Cppreference совершенно неверно;он не имеет «точно такого же эффекта, как пользовательский конструктор с пустым телом и пустым списком инициализатора».И не предполагается.
Если вы хотите немного глубже понять концепцию инициализации значения, подумайте об этом.
int i{};
Это гарантированно даст значение 0для i
.Поэтому разумно, что это:
struct S{int i;};
S s{};
Если также даст значение 0 для s.i
.Как это происходит?Поскольку инициализация значения будет инициализироваться нулями s
.
Так как же пользователь говорит, что он этого не хочет или хочет какую-то особую форму инициализации?Вы сообщаете это так же, как и все остальное: вы добавляете конструктор.В частности, конструктор по умолчанию, который выполняет желаемую форму инициализации.