随着新标准的到来(部分在一些编译器中已经可用),新类型std::unique_ptr被认为是std::auto_ptr的替代品。
它们的用法是否完全重叠(这样我就可以对我的代码进行全局查找/替换(不是说我会这样做,但如果我这样做了),或者我应该意识到一些从阅读文档中不明显的差异吗?
另外,如果它是一个直接的替换,为什么给它一个新名字,而不是改进std::auto_ptr?
随着新标准的到来(部分在一些编译器中已经可用),新类型std::unique_ptr被认为是std::auto_ptr的替代品。
它们的用法是否完全重叠(这样我就可以对我的代码进行全局查找/替换(不是说我会这样做,但如果我这样做了),或者我应该意识到一些从阅读文档中不明显的差异吗?
另外,如果它是一个直接的替换,为什么给它一个新名字,而不是改进std::auto_ptr?
Std::auto_ptr和Std::unique_ptr在某些方面不兼容,并且在其他方面的替换减少。所以,没有查找/替换是不够的。然而,在查找/替换之后,通过编译错误应该可以修复所有问题,除了奇怪的角落情况。大多数编译错误都需要添加std::move。
Function scope variable: 100% compatible, as long as you don't pass it by value to another function. Return type: not 100% compatible but 99% compatible doesn't seem wrong. Function parameter by value: 100% compatible with one caveat, unique_ptrs must be passed through a std::move call. This one is simple as the compiler will complain if you don't get it right. Function parameter by reference: 100% compatible. Class member variable: This one is tricky. std::auto_ptrs copy semantics are evil. If the class disallows copying then std::unique_ptr is a drop in replacement. However, if you tried to give the class reasonable copy semantics, you'll need to change the std::auto_ptr handling code. This is simple as the compiler will complain if you don't get it right. If you allowed copying of a class with a std::auto_ptr member without any special code, then shame on you and good luck.
总之,std::unique_ptr是一个完整的std::auto_ptr。它禁止在编译时使用std::auto_ptr时经常出错的行为。因此,如果您谨慎地使用std::auto_ptr,那么切换到std::unique_ptr应该很简单。如果依赖于std::auto_ptr的奇怪行为,那么无论如何都需要重构代码。
您不能执行全局查找/替换,因为您可以复制auto_ptr(具有已知的结果),但只能移动unique_ptr。任何看起来像
std::auto_ptr<int> p(new int);
std::auto_ptr<int> p2 = p;
至少要变成这样
std::unique_ptr<int> p(new int);
std::unique_ptr<int> p2 = std::move(p);
至于其他区别,unique_ptr可以正确处理数组(它将调用delete[],而auto_ptr将尝试调用delete。
AFAIK, unique_ptr不是直接的替换。它修复的主要缺陷是所有权的隐性转移。
std::auto_ptr<int> a(new int(10)), b;
b = a; //implicitly transfers ownership
std::unique_ptr<int> a(new int(10)), b;
b = std::move(a); //ownership must be transferred explicitly
另一方面,unique_ptr将具有全新的功能:它们可以存储在容器中。
Herb Sutter对GotW #89有一个很好的解释:
What’s the deal with auto_ptr? auto_ptr is most charitably characterized as a valiant attempt to create a unique_ptr before C++ had move semantics. auto_ptr is now deprecated, and should not be used in new code. If you have auto_ptr in an existing code base, when you get a chance try doing a global search-and-replace of auto_ptr to unique_ptr; the vast majority of uses will work the same, and it might expose (as a compile-time error) or fix (silently) a bug or two you didn't know you had.
换句话说,虽然全局搜索和替换可能会暂时“破坏”您的代码,但无论如何您都应该这样做:修复编译错误可能需要一些时间,但从长远来看将为您省去更多麻烦。