Значения по умолчанию в списках инициализаторов 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 говорит:
объект, инициализатор которого представляет собой пустой набор скобок, т. е. (), должен быть инициализирован значением.
значение-инициализация - это, проще говоря, конструкция по умолчанию для классов и нулевая инициализация для неклассовых типов.