通八洲科技

c++中如何使用smart pointers智能指针_c++ unique_ptr与shared_ptr用法

日期:2026-01-01 00:00 / 作者:尼克
该用 std::unique_ptr 而不是 std::shared_ptr 的核心判断标准是所有权是否需要共享:unique_ptr 表示独占所有权,转移后原指针自动置空;shared_ptr 通过引用计数允许多方共享同一对象。

什么时候该用 std::unique_ptr 而不是 std::shared_ptr

核心判断标准是所有权是否需要共享:std::unique_ptr 表示独占所有权,转移后原指针自动置空;std::shared_ptr 通过引用计数允许多方共享同一对象。如果只是临时封装堆内存、函数返回资源、或作为容器元素管理单个对象,优先选 unique_ptr —— 它零开销、无原子操作、不引入循环引用风险。

常见误用场景:

unique_ptr 的正确构造与移动语义

unique_ptr 不支持拷贝,只支持移动。直接赋值或传参时若忘记 std::move(),编译器会报错:use of deleted function 'std::unique_ptr::unique_ptr(const std::unique_ptr&)'

推荐写法:

std::unique_ptr p1 = std::make_unique(42);
std::unique_ptr p2 = std::move(p1); // ✅ 正确:显式移动
// std::unique_ptr p3 = p1; // ❌ 编译失败

shared_ptr 的循环引用与 weak_ptr 解法

两个 shared_ptr 相互持有对方管理的对象(例如双向链表节点、父子对象关系),会导致引用计数永远不为 0,内存泄漏。这是 shared_ptr 最典型的陷阱。

解决方式不是少用 shared_ptr,而是识别“观测性引用”并替换为 std::weak_ptr

struct Node {
    std::shared_ptr next;
    std::weak_ptr prev; // 避免循环引用
};

auto a = std::make_shared();
auto b = std::make_shared();
a->next = b;
b->prev = a; // ✅ 不增加 a 的引用计数

自定义删除器与数组支持的细节差异

unique_ptrshared_ptr 都支持自定义删除器,但语法和默认行为不同:

// unique_ptr 数组(推荐)
std::unique_ptr arr = std::make_unique(10);

// shared_ptr 数组(C++17+)
std::shared_ptr arr2(new int[10], std::default_delete());
真正难的不是记住语法,是每次写 shared_ptr 时多问一句:“这个对象,到底有没有别的地方也该负责它的生死?”——没想清楚就先用 unique_ptr