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的构造函数声明为:
普通的构造函数会持有封装对象,拷贝构造函数会交换封装对象的所有权:
析构函数直接释放所持对象:
std::auto_ptr 的成员函数非常简单,我们常用的就是get函数,就是获取封装对象的指针。另外还有release和reset。release函数让auto_ptr放弃所有权,reset函数释放原持有对象,重新赋予新的封装对象。具体实现如下:
另外std::auto_ptr重载的一些操作符。除了*操作符实现了指针的类似功能外,我们需要注意的是=操作符。=操作符会交换所有权,并进行一些其它必要操作,比如释放原来auto_ptr持有的所有权,释放现在auto_ptr持有的对象,现在的auto_ptr持有新的对象的所有权,具体实现如下:
我们仔细想一下就会发下这样一种情况:
这种情况就产生了两个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代替它的原因吧。
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代替它的原因吧。
相关文章推荐
- 《The C++ Standard Library》第50页 关于传递auto_ptr的问题
- More Effective C++ Item 附2:一个auto_ptr的实现实例
- C++ - 智能指针 Vs. auto_ptr
- 关于C++中的auto_ptr
- c++ standard library 学习笔记-auto_ptr<T> 注意事项
- C++的auto_ptr
- C++ 只能指针 auto_ptr 原理 解析 源码
- C++标准模板库中的auto_ptr
- C++垃圾回收器的实现(附auto_ptr 与CComPtr区别)
- [C++][STL]智能指针:auto_ptr
- C++可怜的内存管理机制漫谈及奇怪补救auto_ptr介绍
- c++中的智能指针auto_ptr
- C++中的auto_ptr (修改版本)
- [转载]C++的智能指针auto_ptr做了些什么
- C++ auto_ptr智能指针的用法
- VC c++中auto_ptr的转移问题
- C++的auto_ptr
- (大卫的阅读笔记)More Effective C++ Item 附2:一个auto_ptr的实现实例
- C++之auto_ptr
- C++ Standard Stl -- SGI STL源码学习笔记(01) auto_ptr