我知道默认情况下会初始化一些POD变量,但其他变量则不会。 (POD类型包括int
,float
,指针,联合,POD类型数组,POD类型结构等。)
范围和存储类如何影响POD类型的默认初始化?
具体而言,将隐式初始化以下哪一项:
new
我知道存在一些与这些情况有关的问题,但没有全面的问题(它们仅针对具体情况)。
答案 0 :(得分:14)
具有自动存储持续时间的局部变量未自动初始化。由于使用未初始化的变量会产生未定义的行为,因此即使多余的变量显而易见,也应该明确初始化变量。
关于零初始化的POD类型,C ++ 03标准 3.6.2非本地对象的初始化状态:
§1 静态存储时间(3.7.1)的对象在进行任何其他初始化之前应零初始化(8.5) 。使用常量表达式进行零初始化和初始化统称为静态初始化;所有其他初始化是动态初始化。具有使用常量表达式(5.19)初始化的静态存储持续时间的POD类型(3.9)的对象应在进行任何动态初始化之前进行初始化。
因此,标准保证
静态存储持续时间的POD类型(无论其范围是什么)将被零初始化。
类的POD成员(在构造函数中没有显式初始化)
这种情况在 12.6.2初始化基础和成员中描述,表明(选定的部分):
如果某个给定的非静态数据成员或基类没有被mem-initializer-id命名(包括没有mem-initializer-list的情况,因为构造函数没有ctor-initializer ),然后:
- 如果实体是非静态数据成员 ...,并且实体类是非POD 类,则该实体默认初始化(8.5)......
- 否则,实体未初始化 ...
在对类X的构造函数的调用完成之后,如果X的成员既没有在构造函数的mem-initializers中指定,也没有在default-initialized中指定,也没有在value-initialized中指定,也没有在执行期间给出一个值构造函数,成员具有不确定的值。
示例:
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 !!!
}
答案 1 :(得分:7)
如果我们只讨论POD,那么只有本地和全局静态和外部变量,因为它们必须在某处定义。
分配有new
的POD也会初始化有时 - 如果您明确初始化:
int* x = new int();
将int
初始化为0
,x
指向该int* x = new int;
,而
x
将int
指向未初始化的struct X
{
int x;
};
X x; //x.x is not initialized
X y = X(); //y.x is 0
。
有时 - POD类成员 - 可以显式初始化它们(不在构造函数中):
{{1}}