随着新标准的到来(某些编译器中已经有部分可用),新类型std::unique_ptr
应该是std::auto_ptr
.
它们的用法是否完全重叠(所以我可以对我的代码进行全局查找/替换(不是我会这样做,但如果我这样做了))还是我应该知道阅读文档中不明显的一些差异?
此外,如果它是直接替换,为什么要给它一个新名称而不仅仅是改进std::auto_ptr
?
随着新标准的到来(某些编译器中已经有部分可用),新类型std::unique_ptr
应该是std::auto_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
.
std::auto_ptr
并且std::unique_ptr
在某些方面是不兼容的,而在其他方面则是替代品。因此,没有查找/替换还不够好。但是,在通过编译错误进行查找/替换后,应该可以修复所有问题,除了奇怪的极端情况。大多数编译错误都需要添加std::move
.
unique_ptr
s 必须通过std::move
调用传递。这很简单,因为如果你做的不对,编译器会抱怨。std::auto_ptr
s 复制语义是邪恶的。如果该类不允许复制,则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::auto_ptr
' 的奇怪行为,那么无论如何您都需要重构您的代码。
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有一个很好的解释:
与 auto_ptr 有什么关系?auto_ptr 最慷慨地描述为在 C++ 具有移动语义之前创建 unique_ptr 的勇敢尝试。auto_ptr 现在已弃用,不应在新代码中使用。
如果您在现有代码库中有 auto_ptr,当您有机会尝试将 auto_ptr 全局搜索并替换为 unique_ptr 时;绝大多数用途都是一样的,它可能会暴露(作为编译时错误)或修复(默默地)一两个你不知道的错误。
换句话说,虽然全局搜索和替换可能会暂时“破坏”您的代码,但无论如何您都应该这样做:修复编译错误可能需要一些时间,但从长远来看会为您节省更多麻烦。