智能指针——共享指针
智能指针
共享指针 —— 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
- 适用于函数需要临时共享对象所有权的场景
-
引用传递(推荐)
- 不会触发拷贝,也不会改变引用计数
- 可使用
const shared_ptr<T>&防止修改指针本身 - 适用于函数只使用对象、不接管所有权的场景
-
作为返回值
- 返回
shared_ptr表示将对象的共享所有权传递给调用方 - 支持链式调用,语义清晰
- 编译器会自动处理拷贝或移动,无需额外干预
- 返回
小结
- 需要共享所有权 →
shared_ptr - 只使用对象 →
const shared_ptr<T>& - 避免滥用值传递,减少不必要的引用计数变动

浙公网安备 33010602011771号