关闭

C++ auto_ptr

标签: C++ STLC++
172人阅读 评论(0) 收藏 举报
分类:
        std::auto_ptr属于STL库,但是在C++11中已经被废除掉了,至于为什么被费除掉,我们稍后再看。
        std::auto_ptr的作用是控制一个对象的生命周期,内部持有对象的所有权,保存着对象的指针。它的实现非常简单,内部仅仅维护一个对象指针(the wrapped object pointer),在构造函数中构造封装的对象,在析构函数中释放。
        std::auto_ptr的构造函数声明为:
        explicit auto_ptr (X* p=0) throw();
        auto_ptr (auto_ptr* a) throw();
        template<class Y>
        auto_ptr (auto_ptr<Y>& a) throw();
        auto_ptr (auto_ptr_ref<X> r) throw();

    
        普通的构造函数会持有封装对象,拷贝构造函数会交换封装对象的所有权:
</pre><pre name="code" class="cpp">        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() _NOEXCEPT
        {    // destroy the object
        delete _Myptr;
        }


        std::auto_ptr 的成员函数非常简单,我们常用的就是get函数,就是获取封装对象的指针。另外还有release和reset。release函数让auto_ptr放弃所有权,reset函数释放原持有对象,重新赋予新的封装对象。具体实现如下:
        _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;
        }


        另外std::auto_ptr重载的一些操作符。除了*操作符实现了指针的类似功能外,我们需要注意的是=操作符。=操作符会交换所有权,并进行一些其它必要操作,比如释放原来auto_ptr持有的所有权,释放现在auto_ptr持有的对象,现在的auto_ptr持有新的对象的所有权,具体实现如下:
        _Myt& operator=(_Myt& _Right) _THROW0()
        {    // assign compatible _Right (assume pointer)
        reset(_Right.release());
        return (*this);
        }


        我们仔细想一下就会发下这样一种情况:
        int* p = new int();
        std::auto_ptr p1(p);
        std::auto_ptr p2(p);

        这种情况就产生了两个auto_ptr拥有同一个对象的所有权,那么在释放的时候就会产生两次析构的情况,所以就会有“防止两个auto_ptr拥有一个对象”的建议。但是这个问题在std::unique_ptr中也同样可以出现,所以就需要靠使用者自己注意了吧。
        std::auto_ptr的最主要的问题在于所有权的转移问题。无论是在拷贝构造函数中还是在赋值运算符中,所有权都会进行转移。std::auto_ptr的本意我猜是为了表述所有权是唯一一个管理者持有的,所以赋值复制操作都会转移所有权,保持唯一一个管理者,这样做有很大的好处,也符合智能指针的使用策略,但是这种功能会造成过于简单地改变所有权,在很多操作上会造成莫名其妙的情况,比如在std::vector<T>中push_back后,莫名其妙地失去所有权了,这和平时的编程情况不一样,造成了一种"特别"的结果,很容易在使用上造成理解上的bug,导致意想不到的结果。这也可能是C++11废除std::auto_ptr而用std::unique_ptr代替它的原因吧。


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:10601次
    • 积分:255
    • 等级:
    • 排名:千里之外
    • 原创:15篇
    • 转载:2篇
    • 译文:0篇
    • 评论:4条
    文章分类
    最新评论