Значения по умолчанию в списках инициализаторов С++ - программирование
Подтвердить что ты не робот

Значения по умолчанию в списках инициализаторов С++

Я только вчера узнал, что указание параметров для элементов списка инициализаций является необязательным. Однако каковы правила того, что происходит в этом случае?

В приведенном ниже примере инициализируется ptr до 0, переключается на false и Bar по умолчанию построено? Я предполагаю, что этот вопрос является своего рода избыточным, потому что в списках инициализаторов мало смысла, если неопределенные значения аргументов == undefined.

Могу ли я также указать на раздел стандарта С++, в котором указано поведение в случае элементов списка инициализаций, не заданных аргументами?

class Bar
{
    Bar() { }
};

class SomeClass;
class AnotherClass
{
public:
    SomeClass *ptr;
    bool toggle;
    Bar bar;

    AnotherClass() : ptr(), toggle(), bar() { }
    // as opposed to...
    // AnotherClass() : ptr(NULL), toggle(false), bar(Bar()) { }
};
4b9b3361

Ответ 1

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

Стандарт С++ 11 определяет это поведение в 12.6.2/7:

Используется список выражений-list или braced-init-list в mem-initializer для инициализации указанного подобъекта (или, в случае делегирующий конструктор, полный объект класса) в соответствии с правила инициализации 8.5 для прямой инициализации.

В свою очередь, 8.5/10 гласит:

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

Параграф 8.5/7 определяет инициализацию значения:

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

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

И, наконец, 8.5/5 определяет нуль-инициализацию:

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

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

Ответ 2

В приведенном ниже примере инициализируется ptr до 0, переключается на false, а Bar по умолчанию - построено?

Да. Если инициатор-член появляется в списке инициализации с пустыми круглыми скобками, то этот элемент инициализируется значением. Это означает, что числовые типы будут инициализированы до нуля, указатели на нуль и классы с конструкторами по умолчанию, использующие этот конструктор.

Если вы не включаете участника в список инициализации вообще, тогда он будет инициализироваться по умолчанию; в таком случае. числовые и указательные типы останутся неинициализированными.

Могу ли я также указать на раздел стандарта С++, в котором указано поведение в случае элементов списка инициализаций, не заданных аргументами?

С++ 11 12.6.2/7 указывает, что правила те же, что и для прямой инициализации.

С++ 11 8.5/16 указывает, что если инициализатор (), объект инициализируется значением.

С++ 11 8.5/7 определяет инициализацию значения.

Ответ 3

Инициализация рассматривается в [dcl.init] (aka 8.5)

В пункте 10 говорится:

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

Инициализация значения - это просто построение по умолчанию для классов и нулевая инициализация для неклассовых типов.