所有框架的智能指针(STL/Qt/其他),本质仅分为独占式和共享式两类,弱引用指针是共享指针的补充(解决循环引用),Qt 还提供了专属的 QPointer 用于野指针防护。本文从核心原理、使用场景、避坑技巧到实战排查,全面解析各类智能指针的用法,内容兼顾 STL 和 Qt。
一、独占式智能指针
1.1 对应类型与核心原理
- STL 对应:
std::unique_ptr - Qt 对应:
QScopedPointer
核心原理:将裸指针封装为智能指针对象的成员变量,利用局部对象的生命周期自动管理资源—— 智能指针对象出作用域时,析构函数会自动释放封装的裸指针;且独占指针禁用拷贝构造 / 赋值,保证一个资源仅被一个智能指针对象管理,实现真正的'独占'。
1.2 为何不用裸指针直接 new/delete?
手动管理裸指针时,若函数存在多分支退出(if-else/return/异常),资源释放会变得异常繁琐,且极易遗漏:
- 用
goto统一释放:语法上允许,但破坏代码结构化,极力避免使用; - 各分支单独释放:需在每一个 return/break 处写 delete,代码冗余,若后续维护新增分支,极易忘记释放指针,直接导致内存泄漏。
而独占智能指针无需关心退出分支,只要出作用域就会自动释放资源,从根本上解决多分支资源泄漏问题。
1.3 关键使用规范:原子构造,避免构造异常
若通过裸指针直接构造独占指针,裸指针 new和智能指针构造是两个独立操作,非原子性 —— 极端情况下可能出现'裸指针 new 成功,但智能指针构造失败',导致裸指针成为野指针,资源永远无法释放。
正确做法:使用专属的原子构造方法,保证'资源创建 + 智能指针构造'要么全成功,要么全失败:
- STL:
std::make_unique<T>(args...)(C++14 及以上支持,C++11 无此方法); - Qt/QScopedPointer:无官方原子构造方法,C++11/Qt 项目需谨慎使用裸指针构造,尽量缩小作用域。
示例(STL 原子构造):
#include <memory>
// 正确:原子构造,避免构造异常
std::unique_ptr<int> u_ptr = std::make_unique<int>(10);
// 不推荐:非原子构造,存在构造失败风险
int* raw_ptr = new int(10);
std::unique_ptr<int> u_ptr2(raw_ptr);
二、共享式智能指针
2.1 对应类型与核心原理
- STL 对应:
std::shared_ptr

