я знаю, некоторые POD переменные инициализируются по умолчанию, а другие нет. (Типы POD включают int
, float
, указатели, объединения, массивы типов POD, структуры типов POD и т. д.)
Как область и класс хранения влияют на инициализацию по умолчанию типов POD?
В частности, что из следующего будет неявно инициализировано:
new
Я знаю, что существуют некоторые вопросы, касающиеся некоторых из этих ситуаций, но они не являются исчерпывающими (они касаются только конкретных ситуаций).
Локальные переменные с автоматической продолжительностью хранения не инициализируются автоматически. Поскольку использование неинициализированных переменных производит неопределенное поведение, Хорошей практикой является явная инициализация переменных, даже если они избыточны.
О типах POD, которые инициализируются нулями, стандарт C ++ 03 3.6.2 Инициализация нелокальных объектов состояния:
§ 1 Объекты с статическая продолжительность хранения (3.7.1) должен быть нулевой инициализируется (8.5) до любой другой инициализации. Нулевая инициализация и инициализация с постоянным выражением вместе называются статической инициализацией; все остальные инициализации — это динамическая инициализация. Объекты типов POD (3.9) со статической продолжительностью хранения, инициализированные с помощью константных выражений (5.19), должны быть инициализированы перед любой динамической инициализацией.
Таким образом, стандартно гарантируется, что типы POD с статическая продолжительность хранения (какой бы ни была их область) будет инициализироваться нулями.
POD-члены класса (без явной инициализации в конструкторе)
Эта ситуация описана в 12.6.2 Инициализация баз и членов, который заявляет (выбранные части):
Если данный нестатический элемент данных или базовый класс не именуются с помощью mem-initializer-id (включая случай, когда нет mem-initializer-list, потому что конструктор не имеет ctor-initializer), тогда:
— Если субъект является нестатический элемент данных…, и класс сущности это не POD класс, сущность по умолчанию инициализируется (8,5) …
— В противном случае сущность не инициализируется…
После завершения вызова конструктора для класса X, если член X не указан ни в mem-инициализаторах конструктора, ни в инициализированных по умолчанию, ни в инициализированных значениях, ни в качестве значения во время выполнения тела конструктора, член имеет неопределенную ценность.
Пример:
class C
{
public:
C(int x, int z) : x(x), z(z) { }
int x, y, z;
};
int main(void)
{
C* c = new C(1,3);
std::cout << c->y; // value of y is undetermined !!!
}
Если мы говорим только о POD, то только локальная и глобальная статика а также внешние переменные потому что они должны быть определены где-то.
POD, выделенные с new
также инициализируются иногда — если вы делаете инициализацию явной:
int* x = new int();
создаст int
инициализирован в 0
с x
указывая на это, тогда как
int* x = new int;
буду иметь x
указывают на неинициализированный int
,
Иногда — члены класса POD — они могут быть инициализированы явно (без использования конструктора):
struct X
{
int x;
};
X x; //x.x is not initialized
X y = X(); //y.x is 0