零初始化
来自 cppreference.cn
将对象的初始值设置为零。
目录 |
[编辑] 语法
请注意,这并不是零初始化的语法,零初始化在语言中没有专门的语法。这些是其他类型初始化的示例,它们可能会执行零初始化。
static T 对象 ; |
(1) | ||||||||
T () ; T t T |
(2) | ||||||||
CharT 数组 [ n ] = " 短序列 "; |
(3) | ||||||||
[编辑] 解释
零初始化在以下情况下执行:
零初始化的效果是:
- 如果
T
是联合类型
- 所有填充位都被初始化为零位,并且
- 对象的第一个非静态具名数据成员被零初始化。
- 如果
T
是数组类型,则每个元素都被零初始化。 - 如果
T
是引用类型,则不执行任何操作。
[编辑] 注意
如非局部初始化中所述,未进行常量初始化的静态和线程局部(C++11 起)变量在任何其他初始化发生之前都会被零初始化。如果非类非局部变量的定义没有初始化器,则默认初始化不执行任何操作,使先前零初始化的结果保持不变。
零初始化后的指针是其类型的空指针值,即使空指针的值不是整数零。
[编辑] 示例
运行此代码
#include <iostream> #include <string> struct A { int a, b, c; }; double f[3]; // zero-initialized to three 0.0's int* p; // zero-initialized to null pointer value // (even if the value is not integral 0) std::string s; // zero-initialized to indeterminate value, then // default-initialized to "" by the std::string default constructor int main(int argc, char*[]) { delete p; // safe to delete a null pointer static int n = argc; // zero-initialized to 0 then copy-initialized to argc std::cout << "n = " << n << '\n'; A a = A(); // the effect is same as: A a{}; or 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 的非常量表达式初始化,这并不是一个空指针常量 |
必须用值为 0 的整数常量表达式初始化 必须用值为 0 的整数常量表达式初始化 |
CWG 694 | C++98 | 类类型的零初始化忽略填充 | 填充被初始化为零位 |
CWG 903 | C++98 | 标量类型的零初始化将初始值设置为从值为 0 的整数常量表达式转换而来的值 标量类型的零初始化将初始值设置为从值为 0 的整数常量表达式转换而来的值 |
对象被初始化为从整数字面量0转换而来的值 对象被初始化为从整数字面量0转换而来的值 |
CWG 2026 | C++98 | 零初始化总是被指定为最先发生,甚至在常量初始化之前 零初始化总是被指定为最先发生,甚至在常量初始化之前 |
如果适用常量初始化,则不进行零初始化 如果适用常量初始化,则不进行零初始化 |
CWG 2196 | C++98 | 类类型的零初始化忽略基类子对象 | 它们也零初始化 |
CWG 2253 | C++98 | 不清楚零初始化是否适用于未命名的位域 不清楚零初始化是否适用于未命名的位域 |
它适用(所有填充位都被初始化为零位) 它适用(所有填充位都被初始化为零位) |