某知名大师说过:自从有了智能指针,上一次发生内存泄露还是在2004年当实习生的时候!
由此可见智能指针威力无穷,竟让他8年没发生过内存泄露,我们上一篇给出了auto_ptr的实现方案,今天给出shared_ptr和实现版本,在新标准中auto_ptr已经不复存在了(其实存在不存在也没什么关系,你想用的话随时可以自己写一个啊)
取而代之的是引入了boost的shared_ptr智能指针和其他三个,这是一个引用计数型的类指针,相比auto_ptr。他有一个至关重要的优点——可以当成类型放入容器,这点auto_ptr是办不到的!
根据Effective C++上对shared_ptr的描述,我们很容易想到他的内部实现,以下是我写的实现版本:
template<class _Ty>
class shared_ptr
{
typedef _Ty element_type;
typedef _Ty* pointer;
private:
_Ty* _ptr;
static std::size_t n_count;
static void change_count_num(bool )throw();
public:
explicit shared_ptr(pointer p=0 )throw()
:_ptr(p)
{//构造函数 只能被显示初始化
shared_ptr::change_count_num(true);
//std::cout<<shared_ptr::n_count<<std::endl;
}
shared_ptr(const shared_ptr &sPtr)throw()
:_ptr( sPtr.get() )
{//复制构造函数
shared_ptr::change_count_num(true);
//std::cout<<shared_ptr::n_count<<std::endl;
}
shared_ptr& operator= (const shared_ptr &sPtr)throw()
{//赋值操作符
_ptr = sPtr.get();
shared_ptr::change_count_num(true);
//std::cout<<shared_ptr::n_count<<std::endl;
return *this;
}
template<typename other>
shared_ptr(const shared_ptr<other> &sPtr)throw()
:_ptr( sPtr.get() )
{//重载模版复制函数,用于实现继承体系中的多态性
shared_ptr::change_count_num(true);
}
template<typename other>
shared_ptr& operator= (const shared_ptr<other> &sPtr)throw()
{//赋值操作符
_ptr = sPtr.get();
shared_ptr::change_count_num(true);
return *this;
}
~shared_ptr()throw()
{//析构函数,判断计数是否为0
if(shared_ptr::n_count == 0)
{
delete _ptr;
_ptr = 0;
}
shared_ptr::change_count_num(false); }
pointer get()const throw()
{//get器,RAII的设计原则,参见Effective C++
return _ptr;
}
void release()throw()
{//释放掉对其的拥有,并置于0
_ptr = 0;
shared_ptr::change_count_num(false);
}
pointer operator-> ()throw(){
return _ptr;
}
element_type operator* (){
return *_ptr;
}
operator bool()const throw(){
return _ptr;
}
};
template<typename _Ty>
std::size_t shared_ptr<_Ty>::n_count = -1;
template<typename _Ty>
void shared_ptr<_Ty>::change_count_num (bool flag)
{
flag? ++shared_ptr<_Ty>::n_count : --shared_ptr<_Ty>::n_count;
}
其中对于引用计数的实现,我使用的static成员,用于标识该类的计数,值得说明的主要就是在所有构造函数和赋值函数 使用静态函数change_count_num,传递true表示加1,false表示减1,并在析构函数执行相应的操作,相对较简单,已基本测试!其中注释的地方为测试计数使用的输出语句!