智能指针
共享指针 —— 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<int> s_p2 = s_p1;cout << "s_p1 use_count: " << s_p1.use_count() << endl; // 2cout << "s_p2 use_count: " << s_p2.use_count() << endl; // 2// 通过其中一个指针修改数据*s_p2 = 20;cout << "s_p1 value: " << *s_p1 << endl; // 20cout << "s_p2 value: " << *s_p2 << endl; // 20shared_ptr<int> s_p3 = s_p1;// 重置一个 shared_ptr,引用计数 -1s_p1 = nullptr;cout << "s_p2 use_count: " << s_p2.use_count() << endl; // 2cout << "s_p3 use_count: " << s_p3.use_count() << endl; // 2
}
2. 自定义数据类型
由于 shared_ptr 采用共享所有权的管理方式,因此:
- 不论有多少个
shared_ptr指向同一个自定义对象 - 该对象的析构函数只会被调用一次
- 只有当所有共享该对象的
shared_ptr都被销毁(引用计数为 0)时,对象才会真正释放
这使得 shared_ptr 非常适合用于:
- 多个模块/对象需要共同访问同一资源
- 无法明确资源唯一所有者的场景