智能指针_shared_ptr: 共享智能指针
shared_ptr 是最像指针的智能指针,是boost.smart_ptr库中最有价值、最重要的组成部分,也是最有用的,Boost库的许多组件——甚至还包括其他一些领域的智能指针都使用了shared_ptr.
shared_ptr与scoped_ptr一样包装了new操作符在堆上分配的动态对象,但它实现的是引用计数型的智能指针,可以被自由地拷贝和赋值,在任意的地方共享它,当没有代码使用(引用计数为 0 )它时才删除被包装的动态分配的对象。shared_ptr也可以安全地放在标准容器中,并弥补了auto_ptr因为语义而不能把指针作为STL容器元素的缺陷。
使用:
<span style="font-size:18px;">#include <iostream>
#include <boost/smart_ptr.hpp>
using namaspace std;
using namaspace boost;
int main()
{
int *p = ne int(10);
shared_ptr<int> ps(p);
cout<<*ps<<endl; //->p
shared_ptr<int> ps1 = ps;
shared_ptr<int> ps2;
ps2 = ps1;
return 0;
}
</span>
auto_ptr对象拷贝构造和赋值的同时需要转移拥有权,以避免对同一块空间的对此释放;
而shared_ptr则运用引用计数,在拷贝构造和赋值时,将引用计数加 1,析构时,将引用计数减 1,当引用计数为 0 时,对空间进行释放。
//
实现:
<1>shared_count.h
<span style="font-size:18px;">#ifndef _SHARED_COUNT_H
#define _SHARED_COUNT_H
#include "sp_counted_base.h"
#include "sp_counted_impl_xx.h"
class shared_count
{
public:
template<class Y>
shared_count(Y *p):pi_(new sp_counted_impl_xx<Y>(p))
{}
shared_count(const shared_count &r):pi_(r.pi_)
{
if(pi_ != 0)
{
pi_->add_ref_copy();
}
}
~shared_count()
{
if(pi_ != 0) //释放shared_count所指的空间
pi_->release();
}
public:
long use_count()const
{
return pi_ != 0 ? pi_->use_count : 0;
}
bool unique()const
{
return use_count() == 1;
}
void swap(shared_count &r)
{
sp_counted_base *tmp = r.pi;
r.pi_ = pi_;
pi_ = tmp;
}
private:
sp_counted_base *pi_; //父类指针作为接口,实现多态
};
#endif
</span>
<1-2>sp_counted_base.h
<span style="font-size:18px;">#ifndef _SP_COUNTED_BASE_H
#define _SP_COUNTED_BASE_H
class sp_counted_base
{
public:
sp_counted_base():use_count_(1)
{}
virtual ~sp_counted_base()
{}
public:
virtual void dispose()=0;
void release()
{
if(--use_count_ == 0)
{
dispose(); //析构sp_counted_xx所指的数据空间
delete this; //析构自身sp_counted_imple_xx
}
}
viod add_ref_copy()
{
++use_count_;
}
public:
long use_count()const
{
return use_count_;
}
private:
long use_count_;
};
#endif</span>
<1-3>sp_counted_impl_xx.h
<span style="font-size:18px;">#ifndef _SP_COUNTED_IMPL_XX_H
#define _SP_COUNTED_IMPL_XX_H
#include "sp_counted_base.h"
template<class T>
class sp_counted_impl_xxt:public sp_counted_base
{
public:
sp_counted_impl_xx(T *p):px_(p)
{}
~sp_counted_impl_xx()
{}
public:
virtual void dispose()
{
delete px_;
}
private:
T *px_;
};
#endif</span>
<2>shared_ptr.h
<span style="font-size:18px;">#ifndef _SHARED_PTR_H
#define _SHARED_PTR_H
#include "shared_count.h"
template<class T>
class shared_ptr
{
typedef shared_ptr<T> this_type;
public:
shared_ptr(T *p = 0):px(p),pn(p)
{
cout<<"Create shared_ptr object!"<<endl;
}
shared_ptr(const shared_ptr<T> &r):px(r.px),pn(r.pn)
{}
shared_ptr<T>& operator=(const shared_ptr<T> &r)
{
if(this != &r)
{
this_type(r).swap(*this);
}
return *this;
}
~shared_ptr()
{
cout<<"Free shared_ptr object!"<<endl;
}
pulic:
T& operator*()const
{return *(get());}
T* operator->()const
{return get();}
T* get()const
{return px;}
viod swap(shared_ptr<T> &other)
{
std::swap(px,other.px);
pn.swap(other.pn);
}
public:
long use_count()const
{
return pn.use_count();
}
bool unique()const
{
return pn.unique();
}
private:
T *px;
shared_count pn;
};
#endif
</span>
<3>main.cpp
<span style="font-size:18px;">#include <iostream>
#include "shared_ptr.h"
using namespace std;
int main()
{
int *p = new int(10);
shared_ptr<int> ps(p);
cout<<"ps use_count:"<<ps.use_count()<<endl;
cout<<"ps unique:"<<ps.unique()<<endl;
shared_ptr<int> ps1 = ps;
cout<<"ps use_count:"<<ps.use_count()<<endl;
cout<<"ps unique:"<<ps.unique()<<endl;
shared_ptr<int> ps2;
ps2 = ps1;
return 0;
}</span>
构造顺序:shared_ptr <-- shared_count <-- new sp_counted_impl_xx <-- sp_counted_count