boost源码剖析3----内存管理shared_ptr

        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 <boost\smart_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 <boost\smart_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 <boost\smart_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释放资源。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值