未手动调用构造函数时,C++类数据成员初始化规则及异常值疑问
C++类数据成员初始化问题解答
问题1:所有数据成员都会被初始化为0吗?还是会被自动调用的构造函数赋予随机值?
咱们先把核心规则说清楚:C++的默认构造函数(就是你没手动编写的那个)不会自动初始化int、char、指针这类内置类型成员。这些成员的初始值是未定义的——不是什么“随机生成的值”,而是这块内存之前被使用后留下的残留数据,完全看程序运行时的内存状态,没有任何固定保证。
只有两种场景下,内置类型成员会被默认零初始化:
- 对象通过
new在堆上分配,并且用()初始化,比如Class* obj = new Class(); - 对象是全局变量或者静态变量(比如定义在
main函数外面的对象),这类对象属于全局/静态存储期,会被自动零初始化。
问题2:为什么测试代码输出0 0 1,而非预期的0 0 0?
先看你的测试代码:
#include<iostream> using namespace std; class Class { public: int a,b,c; }; int main() { Class obj; cout<<obj.a; cout<<"\n"; cout<<obj.b; cout<<"\n"; cout<<obj.c; return 0; }
这里的obj是栈上的局部对象,属于自动存储期。它的三个int成员都没有被初始化,所以你读取到的值都是内存里的遗留数据——这次运行碰巧a和b所在的内存区域之前是0,c所在的区域是1,但如果你多运行几次,或者换个编译器、操作系统,结果可能完全不同,甚至每次都变化。
你预期的0 0 0只是个巧合,不是必然结果。本质上,读取未初始化的内置类型成员属于未定义行为,C++标准不保证任何输出结果,编译器甚至可能优化掉这些读取操作,或者产生完全不可预料的结果。
如果想确保成员都初始化为0,你可以手动定义构造函数,或者用C++11及以后的类内初始化:
// 方式1:手动写构造函数,用成员初始化列表 class Class { public: int a,b,c; Class() : a(0), b(0), c(0) {} }; // 方式2:C++11及以后支持的类内直接初始化 class Class { public: int a = 0, b = 0, c = 0; };
这样不管对象是在栈上还是堆上创建,成员都会被正确初始化为0。
内容的提问来源于stack exchange,提问作者Pallav Doshi
相关产品推荐
相关产品推荐

