我知道一些POD变量是默认初始化的,但其他的不是。(POD 类型包括int
、、float
指针、联合、POD 类型的数组、POD 类型的结构等)
范围和存储类如何影响 POD 类型的默认初始化?
具体来说,以下哪一项将被隐式初始化:
- 具有自动存储功能的局部变量
- 静态局部变量
- 静态全局变量
- 外部变量
- 分配的变量
new
- 类的 POD 成员(在构造函数中没有显式初始化)
我知道存在与其中一些情况相关的问题,但并不全面(它们只针对特定情况)。
我知道一些POD变量是默认初始化的,但其他的不是。(POD 类型包括int
、、float
指针、联合、POD 类型的数组、POD 类型的结构等)
范围和存储类如何影响 POD 类型的默认初始化?
具体来说,以下哪一项将被隐式初始化:
new
我知道存在与其中一些情况相关的问题,但并不全面(它们只针对特定情况)。
具有自动存储持续时间的局部变量不会自动初始化。由于使用未初始化的变量会产生未定义的行为,因此即使变量是多余的,显式初始化变量也是一种很好的做法。
关于被零初始化的 POD 类型,C++03 标准3.6.2 非本地对象的初始化状态:
§1具有静态存储持续时间(3.7.1)的对象应在任何其他初始化发生之前进行零初始化(8.5)。零初始化和用常量表达式初始化统称为静态初始化;所有其他初始化都是动态初始化。使用常量表达式 (5.19) 初始化的具有静态存储持续时间的 POD 类型 (3.9) 的对象应在任何动态初始化发生之前进行初始化。
因此,标准保证具有静态存储持续时间(无论它们的范围是什么)的 POD 类型将被零初始化。
类的 POD 成员(在构造函数中没有显式初始化)
这种情况在12.6.2 Initializing bases and members中进行了描述,说明(选定部分):
如果给定的非静态数据成员或基类不是由 mem-initializer-id 命名的(包括由于构造函数没有 ctor-initializer 而没有 mem-initializer-list 的情况),则:
— 如果实体是非静态数据成员...,并且实体类是非 POD类,则实体是默认初始化的(8.5)...
—否则,实体未初始化...
在对类 X 的构造函数的调用完成后,如果 X 的成员既没有在构造函数的 mem-initializers 中指定,也没有默认初始化,也没有值初始化,也没有在构造函数主体执行期间给定值,该成员具有不确定的价值。
例子:
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,那么只有局部和全局静态以及外部变量,因为它们必须在某个地方定义。
分配的 PODnew
有时也会被初始化- 如果您明确初始化:
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