Инициализация инициализации по умолчанию С++ и инициализация значения: которая есть, которая вызывается, когда и как надежно инициализировать член типа шаблона
Мой вопрос несколько перекрывается с этим и несколькими другими подобными. У них есть отличные ответы, но я их прочитал, и я все еще смущен, поэтому, пожалуйста, не рассматривайте этот вопрос как дубликат.
Итак, у меня есть следующий код:
class A {
public: int _a;
}
void main()
{
A inst1;
A* inst2 = new A;
A* inst3 = new A();
}
_a
остается неинициализированным в inst1
и inst2
и инициализируется на 0
в inst3
.
Какая инициализация называется, и почему код работает так, как он есть? Пожалуйста, учтите, что у меня нет стандарта С++ 03, но у меня есть последний проект С++ 11 (я программирую по стандарту '03, хотя), поэтому цитаты из стандарта '03 или ссылки на '11 приветствуются.
Р. S. Первоначальная задача этого исследования состояла в том, чтобы правильно zeto-инициализировать член произвольного типа шаблона T
.
Ответы
Ответ 1
Не так сложно:
A x;
A * p = new A;
Эти две инициализации по умолчанию. Поскольку у вас нет пользовательского конструктора, это означает, что все члены инициализируются по умолчанию. По умолчанию инициализация фундаментального типа типа int
означает "без инициализации".
Далее:
A * p = new A();
Это инициализация значений. (Я не думаю, что существует автоматическая версия этого в С++ 98/03, хотя в С++ 11 вы можете сказать A x{};
, и эта инициализация скобок становится инициализацией значения. Более того, A x = A();
достаточно близко практически, несмотря на то, что вы выполняете копирование, или A x((A()))
, несмотря на прямую инициализацию.)
Опять же, в вашем случае это означает, что все члены инициализируются значением. Инициализация значений для фундаментальных типов означает нулевую инициализацию, которая, в свою очередь, означает, что переменные инициализируются до нуля (которые имеют все основные типы).
Для объектов типа класса, как инициализация по умолчанию, так и инициализация значения вызывают конструктор по умолчанию. То, что происходит тогда, зависит от списка инициализаторов конструктора, и игра продолжается рекурсивно для переменных-членов.
Ответ 2
Да, A inst4 ();
рассматривается как объявление функции. std::string str();
должен быть таким же (т.е. я думаю, вы ошибочно считали, что это сработало).
По-видимому (из здесь), С++ 03 будет иметь inst3._a
be 0, но С++ 98 оставил бы его неинициализированным.