Salooloo
回答者
回答于 2026-10-22
在C++程序设计中,应优先使用C++11标准提供的智能指针(std::unique_ptr、std::shared_ptr、std::weak_ptr)替代裸指针和手动new/delete操作,利用RAII(资源获取即初始化)机制确保对象离开作用域时自动释放内存。
步骤与用法
-
使用
std::unique_ptr管理独占资源- 适用于单一所有者场景。不可拷贝,只能通过
std::move转移所有权。 - 推荐使用
std::make_unique创建实例,避免异常安全问题。
auto ptr = std::make_unique<MyClass>(); - 适用于单一所有者场景。不可拷贝,只能通过
-
使用
std::shared_ptr管理共享资源- 适用于多个指针指向同一对象的场景。内部维护引用计数,当最后一个
shared_ptr销毁时释放内存。 - 必须使用
std::make_shared创建,将控制块与对象内存一次性分配,减少内存碎片并提升性能。
auto sp = std::make_shared<MyClass>(); - 适用于多个指针指向同一对象的场景。内部维护引用计数,当最后一个
-
使用
std::weak_ptr打破循环引用weak_ptr不增加shared_ptr的引用计数,用于观察对象是否存活。- 使用前需调用
lock()方法尝试提升为shared_ptr,若对象已销毁则返回空指针。
判断依据
- 资源生命周期明确且无共享需求时,选
unique_ptr(零额外开销)。 - 资源需在多处共享且生命周期不确定时,选
shared_ptr。 - 存在双向引用或缓存场景时,一端使用
weak_ptr防止引用计数无法归零。
适用条件
- 编译器需支持C++11及以上标准(
make_unique需C++14)。 - 适用于堆上分配的动态内存管理,不适用于栈内存或非内存资源(如文件句柄需自定义删除器)。
常见误区
- 对同一裸指针构造多个
shared_ptr:会导致多次释放(double free)。应始终通过已有shared_ptr拷贝或使用make_shared。 shared_ptr循环引用:两个对象互相持有对方的shared_ptr,导致引用计数永远不为0,引发内存泄漏。必须将其中一方改为weak_ptr。- 混用裸指针与智能指针管理同一对象:智能指针接管后不应再手动
delete,也不应将get()返回的裸指针交给另一个智能指针管理。 - 滥用
shared_ptr:其引用计数的原子操作有性能开销,不需要共享时应默认使用unique_ptr。