Shared_ptr类末班可以指向动态内存分配的对象,支持比较操作,可以搭配STL关联式容器,可以说是最智能的一种指针了,它与scoped_ptr一样是包装了new分配的动态对象,与scoped_ptr不同的是Shared_ptr引入了计数型的智能指针,可以被自由的赋值和拷贝,当引用为0时,才删除引用指向的对象。它的行为最接近原始指针,因此比auto_ptr和scoped_ptr使用范围更广。
shared的本身代码比较复杂,我把它经过一番休整,提取里面的关键部分,摘要如下:
template<class T>
class shared_ptr
{
private:
typedef shared_ptr<T> this_type;
public:
typedef T element_type;
typedef T value_type;
typedef T * pointer;
typedef typename boost::detail::shared_ptr_traits<T>::reference reference;//特性萃取
shared_ptr(): px(0), pn() // never throws in 1.30+ 默认构造函数,指针为空,引用计数为0
{
}
explicit shared_ptr( Y * p ): px( p ), pn( p ) // Y must be complete explicit表示只能显示构造对象,带
{ //构造一个拥有指针 p 的 shared_ptr
boost::detail::sp_enable_shared_from_this( this, p, p );
}
template<class Y, class D>
shared_ptr(Y * p, D d): px(p), pn(p, d)//构造一个拥有指针 p 和删除器 d 的 shared_ptr。
//下面那个构造函数用 a 的一个拷贝分配内存
{
boost::detail::sp_enable_shared_from_this( this, p, p );
}
template<class Y, class D, class A>
shared_ptr( Y * p, D d, A a ): px( p ), pn( p, d, a )
{
boost::detail::sp_enable_shared_from_this( this, p, p );
}
shared_ptr( shared_ptr const & r ): px( r.px ), pn( r.pn ) // never throws
{ //如果 r 为 empty,构造一个 empty shared_ptr,否则,
//构造一个带有 r 的 shares ownership(共享所有权)的 shared_ptr
}
template<class Y>
explicit shared_ptr(weak_ptr<Y> const & r): pn(r.pn) // may throw
{ //构造一个带有 r 的 shares ownership(共享所有权)的 shared_ptr,并存储 r 中所存储指针的一个拷贝
// it is now safe to copy r.px, as pn(r.pn) did not throw
px = r.px;
}
template<class Y>
explicit shared_ptr(std::auto_ptr<Y> & r): px(r.get()), pn()
{ //构造一个 shared_ptr,就像存储了一个 r.release() 的返回值的拷贝
Y * tmp = r.get(); //auto_ptr失去指针的管理权
pn = boost::detail::shared_count(r);
boost::detail::sp_enable_shared_from_this( this, tmp, tmp );
}
void set();
template<class Y> void reset(Y *p);
bool unique() const; //判断是否为指针的唯一所有者
long use_count() const; //当前指针引用计数
private:
template<class Y> friend class shared_ptr;
template<class Y> friend class weak_ptr;
#endif
T * px; // contained pointer
boost::detail::shared_count pn; // reference counter
}; // shared_ptr
用法1:
#include <boostsmart_ptr.hpp>
#include <string>
using namespace std;
using namespace boost;
int main()
{
boost::shared_ptr<int> a(new int(10));
assert(a.unique());
boost::shared_ptr<int> b = a;
cout<<b.use_count()<<endl;//2
//a[3] = 15;
*a = 4;
cout<<*a<<endl;//4
b.reset();
cout<<a.use_count()<<endl;//1
return 0;
}
用法2:工厂函数
智能指针的作用在于消除new和delete的显示调用,但是在上面的例子里为了构造一个堆内存还是调用了new,前面说过,显示的调用delete或new可能会引发一系列问题,那么怎么消除new和delete的显示调用呢,那就要使用到工厂函数make_shared。它的名字模仿了STL中的make_pair,声明如下:template<class T, class ... args> shared_ptr<T>make_ shared(Args ... args);最多可以接受10个参数,它创建一个shared_ptr的对象并返回。下面例子说明它的用法:
#include <boostsmart_ptr.hpp>
#include <string>
#include <vector>
using namespace std;
using namespace boost;
int main()
{
boost::shared_ptr<int> pt2 =
boost::make_shared<int>(int(10));
boost::shared_ptr<vector<string> > str =
boost::make_shared<vector<string> >(10,"test");
return 0;
}
用法3:桥接模式
桥接模式是一种结构设计模式,它把类的具体实现 细节对用户隐藏起来,达到类之间最小的耦合关系。例子如下:
#include <boostsmart_ptr.hpp>
#include <string>
using namespace std;
using namespace boost;
class test
{
private:
class hide;
boost::shared_ptr<hide> p1;
public:
test():p1(new hide){}
void print(){p1->print();}
};
class test::hide
{
public:
hide::hide(){}
void print()
{
cout<<"hide print"<<endl;
}
};
int main()
{
test a;
a.print();
}
用法4:应用与标准容器
int main()
{
typedef vector<boost::shared_ptr<int> > vs;
vs v(10);
int i =0;
for(vs::iterator pos = v.begin(); pos!=v.end();pos++)
{
(*pos) = boost::make_shared<int>(++i);
cout<<**pos<<endl;
}
boost::shared_ptr<int> p =v[9];
*p =88;
cout<<*v[9]<<endl;
return 0;
}
注意vector存储的是shared_ptr,在对itertor解引用时得到shared_ptr,在解引用得到值。
用法5:定制删除器
假设有一个类socket,
class socket
{
private:
int *p;
public:
socket(){}
void close()
{
delete p;
//其它操作
}
}
有一个对象socket s,那我们可以这样调用shared_ptr<socket> p(s,close),当离开作用域时,它会自动调用close释放资源。
最后
以上就是神勇樱桃最近收集整理的关于boost源码剖析3----内存管理shared_ptr的全部内容,更多相关boost源码剖析3----内存管理shared_ptr内容请搜索靠谱客的其他文章。
发表评论 取消回复