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

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

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

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

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()) { }
};

3 ответов


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

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

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

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

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

пункт 8.5 / 7 определяет значение инициализации:

значение-инициализировать объект типа T означает:

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

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

до нуля-инициализировать объект или ссылку типа T означает:

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

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

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

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

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

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

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

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


Initialisations описаны в [РСН.init] (он же 8.5)

пункт 10 говорит:

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

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