При попытке ответить на этот вопрос я нашел что код int* p = new int[10]();
компиляции, прекрасные с компилятором VC9 и, инициализируют целые числа к 0. Таким образом, мои вопросы:
new int;
или new int();
? Последний гарантирует, что инициализировал переменную?Прежде всего, это действительный C++ или это расширение microsoft?
Он действителен в C++, соответствующая часть стандарта - 5.3.4, первый параграф которого содержит грамматику
Гарантируется ли инициализация всех элементов массива?
Да. Параграф 5.3.4/15 гласит, что
Выражение new, создающее объект типа T, инициализирует этот объект следующим образом:
...
- Если новый инициализатор имеет форму (), то объект инициализируется по значению (8.5)
где инициализация по значению для POD означает нулевую инициализацию.
Кроме того, есть ли разница, если я выполню new int; или new int();? Гарантирует ли последний вариант инициализацию переменной?
Да, они отличаются. Согласно приведенной выше цитате new int()
нулевая инициализация целого числа. В предыдущем блоке того же параграфа:
Если new-инициализатор опущен:
Если T - это (возможно, cv-квалифицированный) не-POD тип класса (или его массив), объект инициализируется по умолчанию (8.5). Если T является const-квалифицированным типом, базовый тип класса должен иметь объявленный пользователем конструктор по умолчанию.
В противном случае созданный объект имеет неопределенное значение. Если T является const-квалифицированным типом или (возможно cv-квалифицированным) типом класса POD (или его массивом), содержащим (прямо или косвенно) член const-квалифицированного типа, то программа не сформирована;
поэтому new int
не инициализирует память.
Это допустимый C ++ в соответствии с параграфом 5.3.4 / 1, который здесь сложно цитировать из-за особого форматирования.
Согласно 5.3.4 / 15 элемент инициализируется значением, если используется form (), см. Параграф 8.5, но краткий ответ - да.
Да, есть разница: в первом случае переменная не инициализируется значением и может быть любым, во втором случае значение инициализируется и будет равно нулю.
Из стандарта. "Инициализация по умолчанию объекта типа T означает: - если T не является типом класса POD [случай, подобный вектору], вызывается конструктор по умолчанию для T."
Обозначение конструктора T ()
используется для выражения значения по умолчанию для типа T, которое равно нулю для встроенных типов и конструктора по умолчанию для типов, определяемых пользователем. Конструкция POD ()
производит инициализацию значения и в соответствии со стандартным стандартом, в результате чего все члены и подчлены либо создаются по умолчанию, либо инициализируются нулем.
Вот почему ваш оператор является законным, но инициализирован ли он нулем в соответствии со стандартом; ИМХО, нужен подробный поиск.
НО, я не смог найти в стандарте, где it определяет значение конструкции по умолчанию для встроенных типов .
РЕДАКТИРОВАТЬ: -
struct S { int x; };
void f () {
S s1; // s1.x is uninitialized here
S s2 = S(); // s2.x is zero here
}
Я думаю, что мы часто придумываем собственную интерпретацию того, что означает конструкция по умолчанию, применяемая к встроенным типам; потому что стандарт C ++ не определяет его (по крайней мере, я не смог его найти), и я помню, что Страуструп или Йосуттис говорят, что это означает T ()
, что является описывается как инициализация значения: « ноль преобразован в тип T » для встроенных типов.
Поскольку int *
является встроенным типом, он инициализируется нулем.
Но я действительно не уверен.
Если я могу немного угадать (я уверен, что меня поправят, если я ошибаюсь):
Последний () выполняет инициализацию значения (как это называется в стандартном варианте), в результате чего целое число имеет значение 0 в этом случае.
Это довольно новое дополнение к стандарту (C ++ 03?), Поэтому старые компиляторы могут не поддерживать его и оставлять его унифицированным.
Я помню, что получал много предупреждений об этом при переключении с MSVS 2003 на 2005 (я думаю), когда компилятор сказал, что «этот член будет инициализирован нулем сейчас, а не раньше».