Значение инициализации по умолчанию изменилось в C ++ 11?

C ++ 2003 8.5 / 5 говорит:

к по умолчанию инициализирует объект типа T означает:

— если T является типом класса, отличным от POD (пункт 9), вызывается конструктор по умолчанию для T (и инициализация
плохо сформирован, если T не имеет доступного конструктора по умолчанию);

— если T является типом массива, каждый элемент инициализируется по умолчанию;

— в противном случае объект нулевой инициализируется.

[Акцент добавлен.]

Стандарт C ++ 2011 изменил этот последний элемент на

— иначе, инициализация не выполняется.

Похоже, что это будет серьезным изменением для некоторых программ. Было ли это намеренно?

редактировать

Вот некоторый код для мотивации этого вопроса:

class Foo {
public:
Foo() : m_values() {}

int m_values[3];
};

До C ++ 11 я думал о явном упоминании m_values в конструкторе по умолчанию будет по умолчанию инициализирует этот массив. А так как элементы массива являются скалярными, я ожидал, что для значений будут установлены все значения 0.

В C ++ 11 кажется, что больше нет гарантии, что это произойдет. Но, может быть, как отметил Mooing Duck в комментариях, возможно, это уже не случай инициализации по умолчанию, а какая-то другая форма, которая сохраняет ожидаемое поведение. Цитаты приветствуются.

31

Решение

Конечные эффекты почти одинаковы. В C ++ 03 использование по умолчанию инициализирует был ограничен типом класса не POD, поэтому последний пункт никогда не применялся. В C ++ 11 стандарт упрощает формулировку, устраняя условие относительно того, где использовалась инициализация по умолчанию, и изменяет определение инициализации по умолчанию, чтобы охватить все случаи таким образом, чтобы соответствовать тому, что происходило раньше.

22

Другие решения

В соответствии с cppreference.com (потому что он использует более дружественный язык, чем стандарт):

Инициализация по умолчанию выполняется в трех ситуациях:

3) когда базовый класс или нестатический член данных не упоминается в
список инициализатора конструктора и этот конструктор вызывается.

Инициализация значения выполняется в трех ситуациях:

3,7) когда инициализируется не статический элемент данных или базовый класс
использование инициализатора члена с пустой парой скобок or braces (since C++11)

Обратите внимание, что часть C ++ 11 принадлежит or bracesне со всем абзацем.

А также:

Инициализировать значение объекта типа T означает:
— если T является типом массива, то каждый элемент инициализируется значением;
— иначе объект инициализируется нулями

Так что в C ++ 11 по умолчанию инициализация не инициализирует нулями членов, но Значение инициализация делает.

3

Строго говоря, определение по умолчанию инициализирует изменился с C ++ 03 на C ++ 11. Но нужно также учитывать, что изменились ситуации, когда объект является _default-initialize_d:

§8.5p9 C ++ 03 гласит:

Если для объекта не указан инициализатор, и объект имеет (возможно, cv-квалифицированный) тип не-POD класса (или его массив), объект должен инициализироваться по умолчанию; если объект имеет константный тип, базовый тип класса должен иметь объявленный пользователем конструктор по умолчанию. В противном случае, если инициализатор не указан для нестатического объекта, объект и его подобъекты, если таковые имеются, имеют неопределенное начальное значение; если объект или какой-либо из его подобъектов имеют константный тип, программа некорректна.

§8.5p11 C ++ 11 гласит:

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

Как уже отмечал @JamesKanze, по умолчанию инициализация выполняется в C ++ 03, когда не указан инициализатор для объекта типа класса, отличного от POD. В C ++ 11 объект (произвольного типа) по умолчанию инициализируется если инициализатор не указан. Из-за этого изменения определение по умолчанию инициализирует также должен был быть изменен, чтобы быть совместимым с C ++ 03.


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

2
По вопросам рекламы [email protected]