先看auto_ptr,因为它比较简单。既然它在标准库里,那么我们就在gcc的代码中找,恩,最后确定在libstdc++-v3/include/backward/auto_ptr.h里面。说实话,auto_ptr真是太简单了,里面的私有变量就一个:
private:
_Tp* _M_ptr;
其它操作皆是围绕这个进行的,你自己猜都能猜到,看看吧,构造函数中的一个:
C++:
析构函数:- explicit
- auto_ptr(element_type* __p = 0) throw() : _M_ptr(__p) { }
C++:
重载的赋值运算符:- ~auto_ptr() { delete _M_ptr; }
C++:
调用了自己的reset和release方法,按住不表,下面会介绍。重载的提领运算符:- template<typename _Tp1>
- auto_ptr&
- operator=(auto_ptr<_Tp1>& __a) throw()
- {
- reset(__a.release());
- return *this;
- }
C++:
- element_type&
- operator*() const throw()
- {
- _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
- return *_M_ptr;
- }
成员运算符:
C++:
- element_type*
- operator->() const throw()
- {
- _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
- return _M_ptr;
- }
get()方法:
C++:
- element_type*
- get() const throw() { return _M_ptr; }
release()方法:
C++:
- element_type*
- release() throw()
- {
- element_type* __tmp = _M_ptr;
- _M_ptr = 0;
- return __tmp;
- }
reset()方法:
C++:
- void
- reset(element_type* __p = 0) throw()
- {
- if (__p != _M_ptr)
- {
- delete _M_ptr;
- _M_ptr = __p;
- }
- }
这些应该没什么难理解的,可能除了那个成员运算符,只说一句: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,只看用到的三个方法:
C++:
呃,还有一个不能漏了,赋值运算符:- bool unique() const // nothrow
- {
- return use_count() == 1;
- }
- void swap(shared_count & r) // nothrow
- {
- sp_counted_base * tmp = r.pi_;
- r.pi_ = pi_;
- pi_ = tmp;
- }
- long use_count() const // nothrow
- {
- return pi_ != 0? pi_->use_count(): 0;
- }
C++:
再回过头去看shared_ptr的源代码:- shared_count & 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;
- }
C++:
- reference operator* () const // never throws
- {
- BOOST_ASSERT(px != 0);
- return *px;
- }
- T * operator-> () const // never throws
- {
- BOOST_ASSERT(px != 0);
- return px;
- }
- T * get() const // never throws
- {
- return px;
- }
- bool operator! () const // never throws
- {
- return px == 0;
- }
- bool unique() const // never throws
- {
- return pn.unique();
- }
- long use_count() const // never throws
- {
- return pn.use_count();
- }
- void swap(shared_ptr<T> & other) // never throws
- {
- std::swap(px, other.px);
- pn.swap(other.pn);
- }
- shared_ptr & operator=( shared_ptr && r ) // never throws
- {
- this_type( static_cast<shared_ptr &&>( r ) ).swap( *this );
- return *this;
- }
这样一切都明了了。所以,auto_ptr和shared_ptr在使用上的区别也好理解了,下面的小程序可以展示:
C++:
- #include <iostream>
- #include <memory>
- #include <boost/shared_ptr.hpp>
- 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<A> aptr1(new A);
- auto_ptr<A> aptr2;
- aptr2 = aptr1;
- aptr2->print(); //Ok
- cout<<"pointer in aptr1 is: "<<aptr1.get()<<endl;
- aptr1->print(); //Wrong!
- A * a = new A;
- shared_ptr<A> sptr1(a);
- shared_ptr<A> sptr2(sptr1); //alright
- sptr2 = sptr1;
- sptr2->print(); //ok
- sptr1->print(); //ok
- int * b = new int;
- shared_ptr<int> sptr3(b);
- shared_ptr<int> sptr4(b); //WRONG!!
- return 0;
- }
No comments:
Post a Comment