您的位置:首页 > 其它

auto_ptr中的auto_ptr_ref

2013-01-08 18:00 295 查看
先看看类auto_ptr的内部实现机制:

 

 template<typename _Tp>  
    class auto_ptr  
    {  
    private:  
      _Tp* _M_ptr;   
    public:  
      typedef _Tp element_type;  
//////****构造函数******/  
explicit 
      auto_ptr(element_type* __p = 0) throw() : _M_ptr(__p) { }  
 
      auto_ptr(auto_ptr& __a) throw() : _M_ptr(__a.release()) { }  
 
      template<typename _Tp1>  
        auto_ptr(auto_ptr<_Tp1>& __a) throw() : _M_ptr(__a.release()) { }  
/*******重载赋值操作***********/ 
auto_ptr&  
      operator=(auto_ptr& __a) throw()  
      {  
    reset(__a.release());  
    return *this;  
      }  
 
      template<typename _Tp1>  
        auto_ptr&  
        operator=(auto_ptr<_Tp1>& __a) throw()  
        {  
      reset(__a.release());  
      return *this;  
    }  
//********析构****/  
      ~auto_ptr() { delete _M_ptr; }  
/*******成员函数****************/ 
element_type*  
      get() const throw() { return _M_ptr; }  
element_type*  
      release() throw()  
      {  
    element_type* __tmp = _M_ptr;  
    _M_ptr = 0;  
    return __tmp;  
      }  
void  reset(element_type* __p = 0) throw()  
      {  
    if (__p != _M_ptr)  
      {  
        delete _M_ptr;  
        _M_ptr = __p;  
      }  
      }  
/*********以下就是auto_ptr不同于其他智能指针的地方*********/ 
template<typename _Tp1>  
    struct auto_ptr_ref  
    {  
      _Tp1* _M_ptr;  
        
      explicit 
      auto_ptr_ref(_Tp1* __p): _M_ptr(__p) { }  
    };  
auto_ptr(auto_ptr_ref<element_type> __ref) throw()  
      : _M_ptr(__ref._M_ptr) { }  
        
      auto_ptr&  
      operator=(auto_ptr_ref<element_type> __ref) throw()  
      {  
    if (__ref._M_ptr != this->get())  
      {  
        delete _M_ptr;  
        _M_ptr = __ref._M_ptr;  
      }  
    return *this;  
      }  
        
      template<typename _Tp1>  
        operator auto_ptr_ref<_Tp1>() throw()  
        { return auto_ptr_ref<_Tp1>(this->release()); }  
 
      template<typename _Tp1>  
        operator auto_ptr<_Tp1>() throw()  
        { return auto_ptr<_Tp1>(this->release()); }  
  };  
}  

 之所以有auto_ptr_def,主要是因为auto_ptr的特性,auto_ptr注重对所指对象的拥有权,不能够有两个或两个以上的auto_ptr类型的指针同时指向一个对象,这就使得其拷贝构造函数的形参是引用类型,而非常引用。于是就出现了这样的问题:

auto_ptr<int>  ptr2( auto_ptr<int>( new int(1) ) );语句不能够通过编译,因为

auto_ptr<int>( new int(1) )是个right-Value,对右值进行引用是非法的;也许会有人想为什么不把拷贝构造函数实现能这样:
auto_ptr(auto_ptr __a) throw() : _M_ptr(__a.release()) { }-----------(1)
这样就会和
auto_ptr(auto_ptr&  __a) throw() : _M_ptr(__a.release()) { }---------(2)
重载错误问题,但是如果只保留(1),那auto_ptr强调对资源拥有权的特性就会消失了,还好Bill Gibbons和Greg ColvinBill Gibbons和Greg Colvin利用模板和重载的差别引入了auto_ptr_ref,
auto_ptr(auto_ptr_ref<element_type> __ref) throw()

      : _M_ptr(__ref._M_ptr) { }-------------------------(3)
是可以和(2)重载共存的,当然auto_ptr  ptr(auto_ptr<int>(new int(1)));可以通过编译了(调用(3)拷贝构造函数)。

同理:auto_ptr ptr = auto_ptr<int>(new int(1))能通过编译也是借助于auto_ptr_ref的功能。
本文出自 “东方快翔” 博客,请务必保留此出处http://hustluy.blog.51cto.com/1792080/502132
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: