Auto

    技术2022-05-11  60

    auto_ptr是std中的一个型别,是“它所指向的对象”的拥有者。auto_ptr是一种智能指针(Smart Poiner)。主要用于防止“在当程序抛出异常的时候,发生资源泄漏”问题的发生。

    auto_ptr的表现如是:当auto_ptr的生命周期结束的时候,那么它指向的对象也会被delete。

     

    语法:std::auto_ptr<ClassName> ptr(new ClassName());

     

    需要:#include <memory>

    auto_ptr的接口定义得非常好,可以像使用其他指针一样来使用它,因为它提供了operator *和operator ->,operator *可以用来提取指针所指向的对象,而operator ->可以访问指针所指向对象的数据成员。但是auto_ptr并没有给出operator ++的运算,这正是为什么C++的某些使用中更多推荐使用引用,而不是指针的原因了。

     

    注意:不能像使用一般指针一样为Smart Pointer赋值。

    Like This:std::auto_ptr<ClassName> ptr(new ClassName());    //OK, Constructor Make It Sostd::auto_ptr<ClassName> ptr = new ClassName();   //Error!

     

    源码:

    template <class _Ty>class auto_ptr;

    template <class _Ty>struct auto_ptr_ref {     // proxy reference for auto_ptr copying    auto_ptr_ref(auto_ptr<_Ty>& _Right) : _Ref(_Right)     {// construct from compatible auto_ptr     }     auto_ptr<_Ty>& _Ref;    // reference to constructor argument };

    template <class _Ty>class auto_ptr {// wrap an object pointer to ensure destruction public:     typedef _Ty element_type;     explicit auto_ptr(_Ty*_Ptr = 0) _THROW0() : _Myptr(_Ptr)     {// construct from object pointer }     auto_ptr(auto_ptr<_Ty>& _Right) _THROW0() : _Myptr(_Right.release())     {// construct by assuming pointer from _Right auto_ptr }     auto_ptr(auto_ptr_ref<_Ty> _Right) _THROW0() : _Myptr(_Right._Ref.release())     {// construct by assuming pointer from _Right auto_ptr_ref }

        template <class _Other>        operator auto_ptr<_Other>() _THROW0()        { //Convert to Compatible auto_ptr            return (auto_ptr<_Other>(*this));        }    template <class _Other>        operator auto_ptr_ref<_Other>() _THROW0()        { //Convert to Compatible auto_ptr_ptr            return (auto_ptr_ref<_Other>(*this));        }    template <class _Other>        auto_ptr<_Ty>& 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()     : _Myptr(_Right.release())     {// construct by assuming pointer from _Right }

        template <class _Ty>        auto_ptr<_Ty>& operator = (auto_ptr<_Ty>& _Right) _THROW0()        { //Assign Compatible _Right(assume pointer)            reset(_Right.release());            return (*this);        }

        template <class _Ty>        auto_ptr<_Ty>& operator = (auto_ptr_ref<_Ty>& _Right)_THROW0()        {//Assign Compatible _Right._Ref(assume pointer)            reset(_Right._ref.release());            return (*this);        }

        ~auto_ptr() { delete Myptr; }    //Destroy The Object.

    _Ty& operator*() const _THROW0()     {// return designated value         return (*_Myptr);

    }

    _Ty *operator->() const _THROW0()     {// return pointer to class object         return (&**this);

    }

    _Ty *get() const _THROW0()     {// 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)     {// destroy designated object and store new pointer         if (_Ptr != _Myptr)             delete _Myptr;         _Myptr = _Ptr;     }

    private:         _Ty *_Myptr; // the wrapped object pointer

    };

    //[Code End~]

     

       

    剖析:1.关于两个运算符的重载operator ->会调用到operator *的重载。return (&**this);看起来很让人费解,是这样的,假设:auto_ptr<ClassName> myPtr(new ClassName());myPtr->member;       //Call Like This. or{myPtr->memFunc();}所以:*this == myPtr;**this == *myPtr == *_Myptr    //Call operator *&**this == _Myptr

    所以你也可以这样修改基类代码,如是修改:    _Ty* operator->() const _THROW0()    {// return pointer to class object         return (&**this);    //return (_Myptr);     } 这样的修改可能会带来其他的隐含错误,只是现在还没有看出来。

     

    2.关于release()和reset()release()成员函数auto_ptr将会放弃先前所指向的对象(资源)所有权,然后返回那个对象的指针,若没有任何拥有,则返回NULL指针。reset()成员函数默认参数为0;即使不设置参数,或者会使得auto_ptr对象放弃任何对象并删除先前拥有的对象资源。若是传入新的指针(不包括先前拥有的对象指针),auto_ptr会delete先前拥有的对象,并拥有新的对象。若是传入该auto_ptr已经拥有的对象,则调用不会产生任何变化。注意:不要将new[]生成的对象指针数组传入,如果需要使用数组,应该考虑STL的容器们。

     

    3.其析构函数就表明了该智能指针的效用来源auto_ptr对象在析构的时候,也就是其生命周期将尽的时候会自动释放它拥有的对象资源。

    注意:auto_ptr作为参数的传参问题以及其他:1.若某个函数是此指针的传递终点,那么auto_ptr,所指的是经过传递得到拥有权的auto_ptr,它将会在函数返回的时候被删除,就是在退栈的时候,它的拥有也被删除了。2.作为某一个函数的返回值的时候,auto_ptr被传递给到一个新的函数中,它的历程就刚刚开始了。3.即使有异常被抛出,auto_ptr也会尽职地删除它拥有的数据。4.不要把auto_ptr作为标准容器的元素,因为在某些动作中原有的指针会交出拥有权。

     

     

    最新回复(0)