零初始化

< cpp‎ | language

设置对象的初始值为零

语法

注意此非零初始化的语法,它在语言中无专门的语法。这些是其他类型的初始化的例子,会进行零初始化。

static T object ; (1)
T () ;

T t = {} ;
T {} ;

(2)

(C++11 起)
CharT array [ n ] = ""; (3)

解释

在下列情形进行零初始化:

1) 在任何其他初始化前,对每个具有静态或线程局部存储期的,不进行常量初始化的具名变量。
2) 作为非类类型变量,和被值初始化的无构造函数的类类型的成员的值初始化序列的一部分,包括未提供初始化器的聚合体元素的值初始化。
3) 以较短的字符串字面量初始化任何字符类型数组时,零初始化数组的剩余部分。

零初始化的效果是:

  • T 是标量类型,则对象初值为显式转换T 的整型常量零。
  • T 是非联合体类类型,则零初始化其所有基类和非静态数据成员,并初始化所有填充位为零位。忽略构造函数,若它存在。
  • T 是联合体类型,则零初始化首个非静态的具名数据成员,并零初始化所有填充位为零位。
  • T 是数组类型,则零初始化每个元素。
  • T 是引用类型,则不做任何事。

注解

非局部初始化中所述,在进行任何其他初始化前,零初始化未被常量初始化静态和线程局部变量。若非类类型非局部变量的定义没有初始化器,则默认初始化不做任何事,不修改先前零初始化的结果。

零初始化的指针是其类型的空指针值,即使空指针的值并非整型的零也是如此。

示例

#include <string>
#include <iostream>
 
struct A {
    int a,b,c;
};
 
double f[3]; // 零初始化为三个 0.0
int* p;   // 零初始化为空指针值
std::string s; // 零初始化为不确定值再默认初始化为 ""
int main(int argc, char* argv[])
{
    A a = A();
    std::cout << a.a << a.b << a.c << '\n';
    static int n = argc; // 零初始化为 0
                         // 然后复制初始化为 argc
    delete p; // 删除空指针是安全的
}

输出:

000

缺陷报告

下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。

DR 应用于 出版时的行为 正确行为
CWG 2026 C++98 曾指定始终首先进行零初始化,甚至先于常量初始化 若适用常量初始化则无零初始化

参阅