智能指针——共享指针

智能指针

共享指针 —— shared_ptr

与独占指针(unique_ptr)不同,共享指针允许多个指针共同管理同一块内存资源,因此 shared_ptr可拷贝(copyable)的。

shared_ptr 的核心机制是:

引用计数(reference count)

每一个 shared_ptr 都会维护一个与其所管理对象关联的计数器:

  • 每拷贝一次 shared_ptr,引用计数 +1
  • 每销毁或重置一个 shared_ptr,引用计数 -1
  • 当引用计数变为 0 时,所管理的对象才会被真正释放

可以通过 use_count() 查看当前的引用计数(主要用于调试)。


使用方式

shared_ptr 的创建方式与 unique_ptr 类似,推荐使用 make_shared 创建对象,以获得更好的异常安全性和性能表现。


1. 基本数据类型

通过拷贝(copy)得到的多个 shared_ptr 具有以下特点:

  • 指向同一块内存地址
  • 可通过任意一个指针访问或修改该内存
  • 引用计数表示当前有多少个 shared_ptr 正在共享该对象

当某个 shared_ptr 被销毁或被置空时,引用计数会相应减少;只要计数不为 0,对象就不会被释放。

点击查看示例代码
int main()
{
    shared_ptr<int> s_p1 = make_shared<int>(10);
    cout << "value: " << *s_p1 << endl;
    cout << "s_p1 use_count: " << s_p1.use_count() << endl;

    // 拷贝 shared_ptr,引用计数 +1
    shared_ptr<int> s_p2 = s_p1;
    cout << "s_p1 use_count: " << s_p1.use_count() << endl; // 2
    cout << "s_p2 use_count: " << s_p2.use_count() << endl; // 2

    // 通过任意一个指针修改数据
    *s_p2 = 20;
    cout << "s_p1 value: " << *s_p1 << endl; // 20
    cout << "s_p2 value: " << *s_p2 << endl; // 20

    shared_ptr<int> s_p3 = s_p1;

    // 重置一个 shared_ptr,引用计数 -1
    s_p1 = nullptr;

    cout << "s_p2 use_count: " << s_p2.use_count() << endl; // 2
    cout << "s_p3 use_count: " << s_p3.use_count() << endl; // 2
}

2. 自定义数据类型

由于 shared_ptr 采用的是共享所有权模型,因此:

  • 不论有多少个 shared_ptr 指向同一个自定义对象
  • 该对象的析构函数只会被调用一次
  • 只有当所有指向该对象的 shared_ptr 都被销毁(引用计数为 0)时,对象才会真正释放

这使得 shared_ptr 特别适合以下场景:

  • 多个模块或对象需要共同访问同一资源
  • 无法明确资源唯一所有者的场景

shared_ptr 与函数参数

在函数中使用 shared_ptr 时,常见方式如下:

  1. 值传递

    • 会触发一次拷贝,引用计数 +1
    • 当函数结束、形参被销毁时,引用计数 -1
    • 适用于函数需要临时共享对象所有权的场景
  2. 引用传递(推荐)

    • 不会触发拷贝,也不会改变引用计数
    • 可使用 const shared_ptr<T>& 防止修改指针本身
    • 适用于函数只使用对象、不接管所有权的场景
  3. 作为返回值

    • 返回 shared_ptr 表示将对象的共享所有权传递给调用方
    • 支持链式调用,语义清晰
    • 编译器会自动处理拷贝或移动,无需额外干预

小结

  • 需要共享所有权 → shared_ptr
  • 只使用对象 → const shared_ptr<T>&
  • 避免滥用值传递,减少不必要的引用计数变动
posted @ 2025-12-24 17:14  Ytytyty  阅读(45)  评论(0)    收藏  举报