您的位置:首页 > 编程语言 > C语言/C++

C++ auto_ptr

2016-08-29 13:45 1691 查看
        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代替它的原因吧。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  C++ STL C++