unique_ptr

来源:互联网 发布:java调用openoffice 编辑:程序博客网 时间:2024/06/05 06:47

      先看看auto_ptr是什么东西,"This class template is deprecated as of C++11. unique_ptr is a new facility with a similar functionality, but with improved security (no fake copy assignments), added features (deleters) and support for arrays. See unique_ptr for additional information."(http://www.cplusplus.com/reference/memory/auto_ptr/?kw=auto_ptr),这里“deprecated”是废弃的意思。“no fake copy assignments”也就是说auto_ptr的拷贝赋值是“假的”,不完全的。也就是说,C++11中,这个unique_ptr可以看成是auto_ptr的改良版,那么看看auto_ptr有什么不好的东西,才被“deprecated”的呢?

      首先auto_ptr有拷贝的语义,“ When an assignment operation takes place between two auto_ptr objects, ownership is transferred, which means that the object losing ownership is set to no longer point to the element (it is set to the null pointer).”,而且很正常的支持auto_ptr1 = auto_ptr2这样的操作,但是改良之后的unique_ptr是不支持上面那么这种“Copy assignment”的,“Notice that this function only performs move assignment. Copy assignment is not supported by unique_ptr (except for nullptr).”(http://www.cplusplus.com/reference/memory/unique_ptr/operator=/),只支持“move assignment”。

// unique_ptr::operator= example#include <iostream>#include <memory>int main () {  std::unique_ptr<int> foo;  std::unique_ptr<int> bar;  foo = std::unique_ptr<int>(new int (101));  // rvalue  bar = std::move(foo);                       // using std::move  std::cout << "foo: ";  if (foo) std::cout << *foo << '\n'; else std::cout << "empty\n";  std::cout << "bar: ";  if (bar) std::cout << *bar << '\n'; else std::cout << "empty\n";  return 0;}Output:foo: emptybar: 101

      然后auto_ptr不可指向动态数组,这个与auto_ptr实现有关系,auto_ptr里面只有一个管理原是指针的参数,所有的自动释放操作都是调用的delete *T;而unqiue_ptr就不一样了:


“A unique_ptr object has two components:
•a stored pointer: the pointer to the object it manages. This is set on construction, can be altered by an assignment operation or by calling member reset, and can be individually accessed for reading using members get or release.
•a stored deleter: a callable object that takes an argument of the same type as the stored pointer and is called to delete the managed object. It is set on construction, can be altered by an assignment operation, and can be individually accessed using member get_deleter.”


      看看原形也是提供两种模板:
non-specialized template <class T, class D = default_delete<T>> class unique_ptr;
array specialization template <class T, class D> class unique_ptr<T[],D>;

直接的拷贝赋值是不可以,但是在函数返回时候可以使用,下面是ok的。

unique_ptr<int> GetVal( ){unique_ptr<int> up(new int(88 );return up;}



      最后一个问题,auto_ptr是不能放在容器里面的,因为他的拷贝赋值是fake的,使用会对上下文造成意想不到的影响,而且一些stl的算法也将失效(内部有很多拷贝)。网上看来的几篇文章也说,unique_ptr是可以放在容器的,但是都是说放,auto_ptr也可以放,但是算法会正确执行么?首先一个确定的问题,放入容器中,肯定会导致原指针权限转移。使用肯定也要倍加小心,从简单上理解,如果算法对于unique_ptr没有特殊处理,那么肯定也会有问题的,因为一些算法要拷贝临时对象,拷贝后权限转移后内部指针同样为null,与auto_ptr差别不大。c++11会不会多unique_ptr有特殊处理呢?

      总结下,unique_ptr没有fake的拷贝赋值方法,只有移动赋值方法,而且支持自定义的清除函数定义。可以在一定程度上防止使用auto_ptr出现的一定误区。

 

参考:

http://blog.csdn.net/pi9nc/article/details/12227887
http://blog.csdn.net/fjb2080/article/details/7527770
http://blog.csdn.net/weiwenhp/article/details/8708281

 

0 0