C++中Boost库shared_ptr智能指针详解与使用规范
本文介绍C++ Boost库中的shared_ptr智能指针,讲解其如何通过引用计数实现对象所有权的共享与自动释放。通过实例演示基本用法,分析其线程安全特性及在STL中的应用,并提供避免内存泄漏和循环引用的关键使用规范。
shared_ptr的基本用法与所有权共享
相比不能共享所有权的scoped_ptr,boost::shared_ptr允许指针间共享对同一对象的管理权。以下代码展示了其核心行为:
#include <string>
#include <iostream>
#include <boost/shared_ptr.hpp>
class implementation
{
public:
~implementation() { std::cout <<"destroying implementation\n"; }
void do_something() { std::cout << "did something\n"; }
};
void test()
{
boost::shared_ptr<implementation> sp1(new implementation());
std::cout<<"The Sample now has "<<sp1.use_count()<<" references\n";
boost::shared_ptr<implementation> sp2 = sp1;
std::cout<<"The Sample now has "<<sp2.use_count()<<" references\n";
sp1.reset();
std::cout<<"After Reset sp1. The Sample now has "<<sp2.use_count()<<" references\n";
sp2.reset();
std::cout<<"After Reset sp2.\n";
}
int main()
{
test();
}
运行该程序将输出:
The Sample now has 1 references
The Sample now has 2 references
After Reset sp1. The Sample now has 1 references
destroying implementation
After Reset sp2.
从结果可见,sp1与sp2同时拥有对象的访问权限。只有当两者都释放所有权(调用reset或销毁)时,底层对象的内存才会被自动回收。这种机制在共享权限的同时实现了内存的自动化管理。
引用计数与内存管理机制
boost::shared_ptr内部维护一个引用计数器。每当新增一个shared_ptr指向该对象时,计数加一;反之减一。仅当计数归零,表明无指针再管理该对象时,才会执行delete释放内存。
初始化sp1时,引用计数为1。
通过赋值生成sp2后,引用计数增加至2。
sp1调用reset释放管理权,计数降为1。
sp2随后调用reset,计数归零,触发对象销毁。
主要特点与优势
与scoped_ptr不同,shared_ptr打破了所有权独占的限制,可广泛适用于各类场景:
容器支持:因其具备拷贝语义,可安全放入STL标准容器中。
线程安全:引用计数的更新操作是原子且线程安全的,适合多线程环境下的资源流转。
安全使用规则
尽管shared_ptr提供了便利,但错误使用仍可能导致问题。请遵循以下规范:
避免混合使用原始指针:不要对shared_ptr管理的对象进行显式delete操作,这会导致重复释放引发的未定义行为。
警惕循环引用:shared_ptr无法自动打破对象间的循环引用链(如A包含B,B又包含A),这将导致引用计数永远不为零从而内存泄漏。遇到此类结构应改用weak_ptr。
谨慎处理临时对象构造:不要在函数参数列表中直接构造shared_ptr,因为编译器求值顺序不确定可能引发异常或泄漏。
以下是错误的参数传递写法:
void test()
{
foo(boost::shared_ptr<implementation>(new implementation()),g());
}
正确的做法是先创建独立的shared_ptr变量,再作为参数传入:
void test()
{
boost::shared_ptr<implementation> sp(new implementation());
foo(sp,g());
}
以上就是Boost库中shared_ptr智能指针的详细内容,更多关于C++智能指针优化的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













