偶然的机会看到boost里还有一个shared_ptr型智能指针,费解,C++标准库里不是有auto_ptr了已经?我们先翻出源代码来看看。
先看auto_ptr,因为它比较简单。既然它在标准库里,那么我们就在gcc的代码中找,恩,最后确定在libstdc++-v3/include/backward/auto_ptr.h里面。说实话,auto_ptr真是太简单了,里面的私有变量就一个:
private:
_Tp* _M_ptr;
其它操作皆是围绕这个进行的,你自己猜都能猜到,看看吧,构造函数中的一个:
[cpp]
explicit
auto_ptr(element_type p = 0) throw() : _M_ptr(p) { }
[/cpp]
析构函数:
[cpp]
~auto_ptr() { delete _M_ptr; }
[/cpp]
重载的赋值运算符:
[cpp]
template
auto_ptr&
operator=(auto_ptr& a) throw()
{
reset(a.release());
return this;
}
[/cpp]
调用了自己的reset和release方法,按住不表,下面会介绍。重载的提领运算符:
[cpp]
element_type&
operator() const throw()
{
_GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
return _M_ptr;
}
[/cpp]
成员运算符:
[cpp]
element_type*
operator->() const throw()
{
_GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
return _M_ptr;
}
[/cpp]
get()方法:
[cpp]
element_type*
get() const throw() { return _M_ptr; }
[/cpp]
release()方法:
[cpp]
element_type
release() throw()
{
element_type tmp = _M_ptr;
_M_ptr = 0;
return tmp;
}
[/cpp]
reset()方法:
[cpp]
void
reset(element_type* p = 0) throw()
{
if (p != _M_ptr)
{
delete _M_ptr;
_M_ptr = __p;
}
}
[/cpp]
这些应该没什么难理解的,可能除了那个成员运算符,只说一句:C++会把foo->bar()翻译成:(foo.operator->())->bar()。
从上面我们可以看出,auto_ptr明显没有计数引用,而shared_ptr和它的最大区别就是它有计数。shared_ptr的源代码在boost/shared_ptr.hpp里。先看它的私有变量:
T * px; // contained pointer
boost::detail::shared_count pn; // reference counter
多了一个引用计数器,是一个boost::detail::shared_count类型,再翻源代码boost/detail/shared_count.hpp,只看用到的三个方法:
[cpp]
bool unique() const // nothrow
{
return use_count() == 1;
}
void swap(shared_count & r)
{
sp_counted_base * tmp = r.pi_;
r.pi_ = pi_;
pi_ = tmp;
}
long use_count() const
{
return pi_ != 0? pi_->use_count(): 0;
}
[/cpp]
呃,还有一个不能漏了,赋值运算符:
[cpp]
sharedcount & operator= (shared_count const & r) // nothrow
{
sp_counted_base * tmp = r.pi;
if( tmp != pi_ )
{
if( tmp != 0 ) tmp->add_ref_copy();
if( pi_ != 0 ) pi_->release();
pi_ = tmp;
}
return *this;
}
[/cpp]
再回过头去看shared_ptr的源代码:
[cpp]
reference operator () const // never throws
{
BOOST_ASSERT(px != 0);
return px;
}
T * operator-> () const
{
BOOST_ASSERT(px != 0);
return px;
}
T * get() const
{
return px;
}
bool operator! () const
{
return px == 0;
}
bool unique() const
{
return pn.unique();
}
long use_count() const
{
return pn.use_count();
}
void swap(shared_ptr & other)
{
std::swap(px, other.px);
pn.swap(other.pn);
}
shared_ptr & operator=( shared_ptr && r )
{
this_type( static_cast( r ) ).swap( *this );
return *this;
}
[/cpp]
这样一切都明了了。所以,auto_ptr和shared_ptr在使用上的区别也好理解了,下面的小程序可以展示:
[cpp]
include
include
include
using namespace boost;
using std::cout;
using std::endl;
using std::auto_ptr;
class A
{
public:
void print()
{
cout<<"hello"<<endl;
}
};
int main()
{
auto_ptr aptr1(new A);
auto_ptr aptr2;
aptr2 = aptr1;
aptr2->print();
cout<<"pointer in aptr1 is: "<<aptr1.get()<print();
A * a = new A;
shared_ptr<a> sptr1(a);
shared_ptr<a> sptr2(sptr1);
sptr2 = sptr1;
sptr2->print();
sptr1->print();
int * b = new int;
shared_ptr sptr3(b);
shared_ptr sptr4(b);
return 0;
}
[/cpp]