智能指针scoped_ptr源码剖析
以下为简化后的源码实现…
#include<iostream>
#include<string>
#include<memory>
#include<cassert>
using namespace std;
//scoped_ptr 指向一个对象,死活不肯交出资源占有权(私有的复制构造函数和赋值运算符),除非你和我一样(swap())
//scoped_ptr 指向一个对象,我想指向另一个对象(reset()),我也不能便宜了别人,我把原来的对象析构掉
//scoped_ptr我指向一个auto_ptr指向对象也是可以滴,但是auto_ptr你该滚蛋了...
template<class T> class scoped_ptr
{
private:
T * px;//T类型的指针
typedef scoped_ptr<T> this_type;//当前指针类型
//将scoped_ptr的复制构造函数和赋值运算符设置为私有,防止外部调用
//这样保证了scoped_ptr的作用就像一个常指针一样(Type * const ptr)
scoped_ptr(scoped_ptr const &);
scoped_ptr & operator=(scoped_ptr const &);
//由于scoped_ptr唯一指向了一个对象,所以相等和不等运算符也没有意义
//同样将其设置为私有,不予以实现
void operator==( scoped_ptr const& ) const;
void operator!=( scoped_ptr const& ) const;
public:
typedef T element_type;//对象类型
// 显示的构造函数,防止隐式转换,默认为空
explicit scoped_ptr( T * p = 0 ): px( p )
{
}
//将auto_ptr的资源所有权转让给当前的scoped_ptr auto_ptr参见我的上一遍文章
explicit scoped_ptr( std::auto_ptr<T> p ) : px( p.release() )
{
}
//析构函数
~scoped_ptr()
{
delete px;
}
//reset函数功能让当前指针指向另一个对象,并将原来的对象析构掉
void reset(T * p = 0)
{
assert( p == 0 || p != px );
this_type(p).swap(*this);
}
T & operator*() const
{
assert( px != 0 );
return *px;
}
T * operator->() const
{
assert( px != 0 );
return px;
}
T * get() const
{
return px;
}
//交换两个指针的指向
void swap(scoped_ptr & b)
{
T * tmp = b.px;
b.px = px;
px = tmp;
}
};
//外部函数,交换两个指针的指向
template<class T> inline void swap(scoped_ptr<T> & a, scoped_ptr<T> & b)
{
a.swap(b);
}
int main()
{
auto_ptr<string> p(new string("20150328"));
cout<<*p<<endl;
scoped_ptr<string> q(p);
cout<<*q<<endl;
scoped_ptr<string> r(new string("20:25"));
cout<<*r<<endl;
swap(q, r);
cout<<*q<<endl;
cout<<*r<<endl;
return 0;
}