零初始化
来自cppreference.com
将一个对象的初始值设为零。
语法
注意零初始化在语言中没有专用语法,因此下列语法不是零初始化语法。这些是可能会进行零初始化的其他初始化的例子。
static T 对象 ;
|
(1) | ||||||||
T () ;
T t T |
(2) | ||||||||
CharT 数组 [ n ] = " 短序列 ";
|
(3) | ||||||||
解释
在下列情形进行零初始化:
零初始化的效果是:
- 如果
T
是标量类型,那么对象的初始值是将整数字面量 0 显式转换到T
的值。 - 如果
T
是非联合体类类型,那么:
- 如果
T
是联合体类型,那么:
- 初始化所有填充位为零位,
- 零初始化对象的首个非静态具名数据成员。
- 如果
T
是数组类型,那么零初始化每个元素。 - 如果
T
是引用类型,那么不做任何事。
注解
如非局部初始化中所述,在进行任何其他初始化前,零初始化所有未被常量初始化的静态和线程局部 (C++11 起)变量。如果非类类型非局部变量的定义没有初始化器,那么默认初始化不做任何事,不修改先前零初始化的结果。
零初始化的指针是其类型的空指针值,即使空指针的值并非整型的零。
示例
运行此代码
#include <string> #include <iostream> struct A { int a, b, c; }; double f[3]; // 零初始化为三个 0.0 int* p; // 零初始化为空指针值(即使该值可能不是整型 0) std::string s; // 零初始化为不确定值 // 再通过 std::string 的默认构造函数默认初始化为 "" int main(int argc, char* argv[]) { delete p; // 可以安全删除空指针 static int n = argc; // 零初始化为 0,然后复制初始化为 argc std::cout << "n = " << n << '\n'; A a = A(); // 效果等同于 A a{}; 或 A a = {}; std::cout << "a = {" << a.a << ' ' << a.b << ' ' << a.c << "}\n"; }
输出:
n = 1 a = {0 0 0}
缺陷报告
下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。
缺陷报告 | 应用于 | 出版时的行为 | 正确行为 |
---|---|---|---|
CWG 277 | C++98 | 指针可能会以值为 0 的非常量表达式进行 初始化,但后者不是空指针常量 |
必须以值为 0 的整数 常量表达式进行初始化 |
CWG 694 | C++98 | 零初始化类类型对象时不会处理填充位 | 填充位会被置零 |
CWG 903 | C++98 | 零初始化标量类型对象时会将初始值设为 从值为 0 的整型常量表达式转换而来的值 |
将该对象初始化为从整数 字面量 0 转换而来的值 |
CWG 2026 | C++98 | 始终首先进行零初始化,甚至先于常量初始化 | 适用常量初始化时不进行零初始化 |
CWG 2196 | C++98 | 零初始化类类型对象时不会考虑基类子对象 | 它们也会被零初始化 |
CWG 2253 | C++98 | 不明确无名位域是否适用零初始化 | 适用(初始化所有填充位为零位) |