Инициализация по умолчанию в C ++ и инициализация значения: какой есть, какой вызывается, когда и как надежно инициализировать член типа шаблона - PullRequest
21 голосов
/ 12 ноября 2011

Мой вопрос несколько совпадает с этим и несколькими другими подобными. У них есть отличные ответы, но я их прочитал и все еще растерялся, поэтому, пожалуйста, не считайте этот вопрос дубликатом.

Итак, у меня есть следующий код:

class A {
    public: int _a;
}

void main()
{
    A inst1;
    A* inst2 = new A;
    A* inst3 = new A();
}

_a остается неинициализированным в inst1 и inst2 и инициализируется в 0 в inst3. Какая инициализация называется какой, и почему код работает так, как работает? Пожалуйста, примите во внимание, что у меня нет под рукой стандарта C ++ 03, но у меня есть последний проект C ++ 11 (хотя я программирую по стандарту '03), поэтому цитаты из стандарта '03 или ссылки на '11 добро пожаловать.

P. S. Первоначальная задача этого исследования состояла в том, чтобы правильно инициализировать элемент произвольного типа шаблона T.

Ответы [ 2 ]

24 голосов
/ 12 ноября 2011

Не так сложно:

A x;
A * p = new A;

Это две инициализация по умолчанию . Поскольку у вас нет пользовательского конструктора, это просто означает, что все члены инициализируются по умолчанию. Инициализация по умолчанию для базового типа, такого как int, означает «без инициализации».

Далее:

A * p = new A();

Это значение инициализации . (Я не думаю, что существует автоматическая версия этого в C ++ 98/03, хотя в C ++ 11 вы можете сказать A x{};, и эта скобка-инициализация становится инициализацией значения. Кроме того, A x = A(); достаточно близок практически, несмотря на то, что copy-initialization или A x((A())), несмотря на то, что direct-initialization .)

Опять же, в вашем случае это просто означает, что все члены инициализированы значением. Инициализация значения для фундаментальных типов означает инициализация нуля , что, в свою очередь, означает, что переменные инициализируются нулем (что имеют все фундаментальные типы).

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

1 голос
/ 12 ноября 2011

Да, A inst4 (); рассматривается как объявление функции. std::string str(); должно быть таким же (т. Е. Я думаю, вы ошибочно подумали, что это работает).

Очевидно (из здесь ), C ++ 03 будет иметь inst3._a равным 0, но C ++ 98 оставил бы его неинициализированным.

...