由auto_ptr的实现说起。

 

源代码为你揭示一切。

c++世界很无奈的一点是,很多东西你必须得看源代码才知晓其中的秘诀。因为技巧太多了。

 

 

 template<class _Ty>
    class auto_ptr;

template<class _Ty>
struct auto_ptr_ref

{    

    // proxy reference for auto_ptr copying

    explicit auto_ptr_ref(_Ty *_Right)
        : _Ref(_Right)
        {  

              // construct from generic pointer to auto_ptr ptr
        }

    _Ty *_Ref;    // generic pointer to auto_ptr ptr
};

 

 

template<class _Ty>
class auto_ptr
{  

 // wrap an object pointer to ensure destruction
public:
    typedef auto_ptr<_Ty> _Myt;
    typedef _Ty element_type;

    explicit auto_ptr(_Ty *_Ptr = 0) _THROW0()    // 显式构造函数
        : _Myptr(_Ptr)
        {  

            // construct from object pointer
        }

    auto_ptr(_Myt& _Right) _THROW0()   // 拷贝构造函数,会导致所有权的转移
        : _Myptr(_Right.release())
        {  

            // construct by assuming pointer from _Right auto_ptr
        }

    auto_ptr(auto_ptr_ref<_Ty> _Right) _THROW0()     // 代理构造函数, 代理对象会被释放。
        {    // construct by assuming pointer from _Right auto_ptr_ref
        _Ty *_Ptr = _Right._Ref;
        _Right._Ref = 0;    // release old
        _Myptr = _Ptr;    // reset this
        }

    template<class _Other>
    operator auto_ptr<_Other>() _THROW0()   // 模板构造函数,从别的类型的auto_ptr构造,比如说从auto_ptr<int>和                 

                                                                         //  auto_ptr<const int>之间的转换
     {  

            // convert to compatible auto_ptr
         return (auto_ptr<_Other>(*this));
      }

    template<class _Other>
        operator auto_ptr_ref<_Other>() _THROW0()
        {  

              // convert to compatible auto_ptr_ref
            _Other *_Cvtptr = _Myptr;    // test implicit conversion
            auto_ptr_ref<_Other> _Ans(_Cvtptr);
           _Myptr = 0;    // pass ownership to auto_ptr_ref,此时转移了所有权
           return (_Ans);
        }

    template<class _Other>
        _Myt& operator=(auto_ptr<_Other>& _Right) _THROW0()   //赋值。会转换所有权
        {  

          // assign compatible _Right (assume pointer)
          reset(_Right.release());
          return (*this);
        }

    template<class _Other>
        auto_ptr(auto_ptr<_Other>& _Right) _THROW0()  //拷贝转换,很危险的函数。底层其实就是裸指针的c语言风格的转换
        : _Myptr(_Right.release())
        {  

          // construct by assuming pointer from _Right
        }

    _Myt& operator=(_Myt& _Right) _THROW0()    // 赋值。会导致所有权的转移
        {    // assign compatible _Right (assume pointer)
        reset(_Right.release());
        return (*this);
        }

    _Myt& operator=(auto_ptr_ref<_Ty> _Right) _THROW0()   //赋值。注意参数只是一个简单的代理类
        {    // assign compatible _Right._Ref (assume pointer)
        _Ty *_Ptr = _Right._Ref;
        _Right._Ref = 0;    // release old
        reset(_Ptr);    // set new
        return (*this);
        }

    ~auto_ptr()
        {    // destroy the object
        delete _Myptr;
        }

    _Ty& operator*() const _THROW0()  ///解引用
        {    // return designated value
 #if _ITERATOR_DEBUG_LEVEL == 2
        if (_Myptr == 0)
            _DEBUG_ERROR("auto_ptr not dereferencable");
 #endif /* _ITERATOR_DEBUG_LEVEL == 2 */

        return (*get());
        }

    _Ty *operator->() const _THROW0()    ///  ->转换
        {    // return pointer to class object
 #if _ITERATOR_DEBUG_LEVEL == 2
        if (_Myptr == 0)
            _DEBUG_ERROR("auto_ptr not dereferencable");
 #endif /* _ITERATOR_DEBUG_LEVEL == 2 */

        return (get());
        }

    _Ty *get() const _THROW0()   /     get函数
        {    // return wrapped pointer
        return (_Myptr);
        }

    _Ty *release() _THROW0()
        {    // return wrapped pointer and give up ownership
        _Ty *_Tmp = _Myptr;
        _Myptr = 0;
        return (_Tmp);
        }

     void reset(_Ty *_Ptr = 0)         所谓 reset, 其本质还是set的语义。不过呢,原来持有的对象被删除了。个人认为返回原来的

                                                        //对象也挺   好的
        {    // destroy designated object and store new pointer
        if (_Ptr != _Myptr)
            delete _Myptr;
        _Myptr = _Ptr;
        }

private:
    _Ty *_Myptr;    // the wrapped object pointer,裸指针
    };

 

以上就是VS2010的auto_ptr的实现了。个人认为,如果你自认为理解不了auto_ptr的实现,还是不要轻易使用的吧,免得惹出一堆bug,你又没法理解。

 

c++的模板语法是很头大,但没办法,模板已成为c++越来越重要的特性了。

 

vs2010已经支持shared_ptr和weak_ptr了,有了他们,你完全可以抛弃auto_ptr了。实际上在日常的应用里,我都是些更加轻量级的类来管理资源,对于局部变量来说,用一个类似于scope holder的类来管理指针的析构。对于类而言,同样的,根据设计需要,加入scope holder或者是引用计数,尽量不用auto_ptr.对于保存指针的容器,编码时尽量注意异常安全,以及内存的释放,这样可以尽最大努力来避免资源泄漏。

 

当然,如果有shared_ptr或者是weak_ptr的话,你就可以放心的使用它们了。

 

如果 你还是很讨厌手动来管理内存, 那你转而去学习java和c#。这两门语言都有GC,会自动回收内存。

 

如果有一天,c++也有了GC,会有这么一天吗?

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值