unique_ptr独占所有权,无运行时开销,析构时立即释放资源;shared_ptr共享所有权,通过引用计数管理,有额外内存和性能开销,需注意循环引用问题。

shared_ptr 和 unique_ptr 是 C++ 中两种常用的智能指针,它们的核心区别在于所有权模型的不同,直接影响资源的管理和生命周期控制。
所有权语义不同
unique_ptr 实现独占式所有权。一个对象只能被一个 unique_ptr 持有,不能复制。如果需要转移所有权,必须使用 std::move。
例如:- unique_ptr
ptr1 = make_unique (42); - unique_ptr
ptr2 = ptr1; // 错误:禁止复制 - unique_ptr
ptr3 = std::move(ptr1); // 正确:转移所有权
此时 ptr1 变为空,ptr3 指向原对象。
shared_ptr 实现共享所有权。多个 shared_ptr 可以指向同一个对象,通过引用计数管理资源。当最后一个 shared_ptr 被销毁时,对象自动释放。
立即学习“C++免费学习笔记(深入)”;
例如:- auto sp1 = make_shared
(100); - auto sp2 = sp1; // 合法:引用计数加1
- sp1 和 sp2 共享同一对象,引用计数为2
性能与开销对比
unique_ptr 几乎没有运行时开销。它通常和裸指针大小一样,操作是零成本抽象,适合对性能敏感的场景。
释放由析构函数直接完成,无需额外数据结构。
shared_ptr 有明显开销。除了指向对象的指针,还维护一个控制块(包含引用计数、弱引用计数等),分配内存更多,访问更慢。
每次复制或销毁都要原子操作修改引用计数,在多线程环境下成本更高。
适用场景建议
优先使用 unique_ptr,除非确实需要共享所有权。
- 类内部管理独占资源时用 unique_ptr
- 工厂函数返回值可用 unique_ptr 表示唯一所有权
- 需要在多个地方共享且不确定谁最后使用时,用 shared_ptr
- 观察者模式中配合 weak_ptr 避免循环引用
资源释放行为差异
unique_ptr 析构时立即释放资源,行为可预测,符合 RAII 原则。
shared_ptr 的释放时机依赖引用计数归零,可能延迟。若存在循环引用(如父子节点互相持有 shared_ptr),会导致内存泄漏,需用 weak_ptr 打破循环。
基本上就这些。选哪个取决于是否需要共享。不需要共享就用 unique_ptr,简单高效;需要共享再考虑 shared_ptr,但注意潜在开销和陷阱。











