shared_ptr在功能上和裸指针基本没有区别,但它实现的是引用计数型的智能指针,可以被自由地拷贝和赋值,在任意地方共享它,当没有代码使用它(引用计数为0)时,它才会删除被包装的动态分配的对象。
在c++历史上出现过无数的计数型智能指针实现,但没有一个比得上boost::shared_ptr,在过去、现在和将来,它都是最好的。
————《boost程序库完全开发指南》罗剑锋
#ifndef _SHARED_PTR_H
#define _SHARED_PTR_H
#include"configure.h"
#include"shared_count.h"
template <class T>
class shared_ptr
{
private:
typedef shared_ptr<T> this_type;
public:
shared_ptr(T *p = 0) : px(p),pn(px) //shared_count pn(px)
{
#ifdef DISPLAY
cout<<"Create shared_ptr"<<endl;
#endif
//px = p;
//pn = px;//shared_count pn;
//pn = px;
}
~shared_ptr()
{
#if defined DISPLAY
cout<<"Free shared_ptr"<<endl;
#endif
}
shared_ptr(const shared_ptr &r):px(r.px), pn(r.pn)
{
#ifdef DISPLAY
cout<<"copy Create shared_ptr"<<endl;
#endif
}
template<class Y>
shared_ptr & operator=(shared_ptr<Y> const& r)
{
if(this != &r)
{
this_type(r).swap(*this);
}
return *this;
}
public:
long use_count()
{
return pn.use_count();
}
/*这里有一个很巧妙的地方,在reset方法里边构造了一个无名的临时对象,这个临时对象在出作用域的时候调动析构函数,把从this那里得到的内存释放出去,设计巧妙,代码简洁*/
void reset()
{
this_type().swap(*this);
}
template <class Y>
void reset(Y & p)
{
this_type(p).swap(*this);
}
void swap(shared_count & r)
{
sp_counted_base * tmp = r.pi_;
r.pi_ = pi_;
pi_ = tmp;
}
T *operator->() const
{
return px;
}
T * get() const
{
return px;
}
T & operator*()const
{
return *px;
}
private:
T * px;
shared_count pn;
};
#endif
shared_count内部只有一个sp_counted_base指针型的变量和简单的几个操作函数
long use_count()const
{
return pi_ != 0 ? pi_->use_count() : 0;
}
bool unique() const
{
return use_count() == 0;
}
bool empty()const
{
return pi_ == 0;
}
我认为最重要的代码在sp_counted_impl中对空间的释放,boost库中有自带的删除器,在这里简单实现,不封装delete
virtual ~sp_counted_impl_p()
{
#if defined DISPLAY
cout<<"Free sp_counted_impl_p"<<endl;
#endif
delete px_;
}
virtual void dispose()
{
delete this;
}
只有当引用计数为0的时候就会调动dispose().
运行这段代码
用vld插件检车内存泄漏
没有内存泄漏。至此,简单的实现了boost库中shared_ptr的部分功能(不包括弱指针)。
后续会进一步的去了解boost库中剩余的智能指针,敬请期待。