17

我知道一些POD变量是默认初始化的,但其他的不是。(POD 类型包括int、、float指针、联合、POD 类型的数组、POD 类型的结构等)

范围和存储类如何影响 POD 类型的默认初始化?

具体来说,以下哪一项将被隐式初始化:

  • 具有自动存储功能的局部变量
  • 静态局部变量
  • 静态全局变量
  • 外部变量
  • 分配的变量new
  • 类的 POD 成员(在构造函数中没有显式初始化)

我知道存在与其中一些情况相关的问题,但并不全面(它们只针对特定情况)。

4

2 回答 2

21

具有自动存储持续时间的局部变量不会自动初始化。由于使用未初始化的变量会产生未定义的行为,因此即使变量是多余的,显式初始化变量也是一种很好的做法。

关于被零初始化的 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 !!!
}
于 2013-03-04T22:33:09.333 回答
11

如果我们只讨论 POD,那么只有局部和全局静态以及外部变量,因为它们必须在某个地方定义。

分配的 PODnew有时也会被初始化- 如果您明确初始化:

int* x = new int();

将创建一个指向它的int初始化对象,而0x

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
于 2013-03-04T22:27:31.540 回答