指针成员必须显式初始化,否则为野指针导致崩溃;默认构造函数不初始化内置指针,其值为随机垃圾地址;推荐用nullptr、raii智能指针或容器替代裸指针,并在所有构造函数中统一初始化。

指针成员在构造函数中必须显式初始化,不能留空或依赖编译器默认行为——否则它会是野指针(未定义值),后续解引用必然崩溃。
为什么不能跳过初始化
编译器生成的默认构造函数对内置类型(如 int*)不做任何初始化,str、buffer 这类指针成员的值是随机的。哪怕你只写 MyClass() {},里面的指针也绝不是 nullptr,而是垃圾地址。
- 野指针 ≠
nullptr:if (ptr)判断可能意外为真,导致非法内存访问 - 析构函数里
delete[] ptr会直接 crash,因为ptr指向不可知区域 - 拷贝构造时若没深拷贝,两个对象共用同一块内存,析构两次就 double-free
推荐的初始化方式
根据资源管理策略选择,但必须明确赋值:
- 无资源场景(占位/延迟分配):统一设为
nullptr,并在所有使用前加if (ptr)检查 - 立即分配资源:用
new或std::make_unique初始化,并确保异常安全(比如用 RAII 容器替代裸指针) - 指向已有数据:用参数接收并赋值,但需注意生命周期——别让指针悬空
- 现代 C++ 更推荐:直接用
std::unique_ptr<t></t>或std::vector<t></t>替代裸指针,构造时自动初始化为空或指定大小,无需手动new/delete
容易被忽略的坑
初始化不是写完就算,还要看上下文是否一致:
- 类有多个构造函数时,每个都得单独初始化指针——漏掉一个,那个分支就埋雷
- 成员初始化列表比构造函数体内赋值更安全:
MyClass() : ptr(nullptr) {}优于MyClass() { ptr = nullptr; }(后者先调默认初始化,再覆盖) - 如果指针指向动态数组,记得记录长度(比如额外存个
size_t len),否则delete[]时无法保证正确性 - 继承体系中,基类指针成员初始化后,派生类构造函数不能再“重新 new”覆盖它而不释放旧资源——这属于资源泄漏
最麻烦的不是初始化本身,而是初始化之后没人检查它是否被意外改写成野值;裸指针一旦脱离 RAII 管理,它的生命周期就完全靠人脑维护,出错只是时间问题。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











