Разница между default-initialize и value-initialize в C ++ 03? - PullRequest
8 голосов
/ 17 августа 2011

Я всегда думал, что создание нового объекта всегда будет вызывать конструктор по умолчанию для объекта, и не имеет значения, был ли конструктор явным или автоматически сгенерирован компилятором.Согласно этому высоко оцененному ответу на другой вопрос, он слегка изменился между C ++ 98 и C ++ 03 и теперь работает так:

struct B { ~B(); int m; }; // non-POD, compiler generated default ctor 
new B;   // default-initializes (leaves B::m uninitialized)
new B(); // value-initializes B which zero-initializes all fields since its default ctor is compiler generated as opposed to user-defined.

Может кто-нибудьскажите мне:

  1. Почему был изменен стандарт, то есть, что дает это преимущество или что теперь возможно, чего не было раньше;
  2. Что точно дают термины "default-initialize""и" значение-инициализация "представляют?
  3. Какая часть стандарта?

1 Ответ

2 голосов
/ 17 августа 2011

Я не знаю, каково обоснование изменения (или того, каким был стандарт раньше), но как это происходит, в основном default-initialization либо вызывает пользовательский конструктор, либо ничего не делает (много ручного махания здесь: это рекурсивно применяется к каждому подобъекту, что означает, что подобъекты с конструктором по умолчанию будут инициализированы, подобъекты без пользовательских конструкторов будут оставлены неинициализированными.

Это соответствует плате только за философию языка, которую вы хотите , и совместима с C во всех типах, совместимых с C. С другой стороны, вы можете запросить значение-инициализацию , и это эквивалентно вызову конструктора по умолчанию для объектов, для которых или инициализируется 0, преобразованным в соответствующий тип для остальных подобъектов.

Это описано в §8.5 Инициализаторы, и навигация по нему не тривиальна. Определения для инициализация нуля , инициализация по умолчанию и инициализация значения - это пятый абзац:

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

- если T является скалярным типом (3.9), объекту присваивается значение 0 (ноль), преобразованное в T;

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

- если T является типом объединения, первый именованный элемент данных объекта89) инициализируется нулями;

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

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

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

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

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

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

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

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

- если T является типом класса, не являющимся объединением, без объявленного пользователем конструктора, то каждый нестатический член данных и компонент базового класса в T инициализируется значением;

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

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

Программа, которая требует инициализации по умолчанию или инициализации значения объекта ссылочного типа, плохо сформирована. Если T является cv-квалифицированным типом, cv-неквалифицированная версия T используется для этих определений инициализации нуля, инициализации по умолчанию и инициализации значения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...