随着新标准的出现(以及某些编译器中已有的部分),新类型std::unique_ptr
应该是std::auto_ptr
的替代品。
他们的用法是否完全重叠(所以我可以对我的代码进行全局查找/替换(不是我会这样做,但如果我这样做))或者我应该注意一些在阅读时不明显的差异文档?
此外,如果它是直接替换(为什么要给它一个新名称),而不仅仅是改进std::auto_ptr
。
答案 0 :(得分:209)
您无法进行全局查找/替换,因为您可以复制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
。
答案 1 :(得分:87)
std::auto_ptr
和std::unique_ptr
在某些方面不兼容,而在其他方面则有所取代。所以,没有找到/替换不够好。然而,在通过编译错误进行查找/替换之后,应该修复除了奇怪的角落情况之外的所有内容。大多数编译错误都需要添加std::move
。
unique_ptr
必须通过std::move
电话。这个很简单,因为如果你做不对,编译器会抱怨。std::auto_ptr
的复制语义是邪恶的。如果班级不允许复制,则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
的奇怪行为,那么无论如何您都需要重构代码。
答案 2 :(得分:33)
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
将具有全新的功能:它们可以存储在容器中。
答案 3 :(得分:26)
Herb Sutter对GotW #89有一个很好的解释:
与auto_ptr有什么关系? auto_ptr最基本的特征是在C ++之前创建unique_ptr的勇敢尝试 有移动语义。 auto_ptr现已弃用,不应使用 在新的代码中。
如果您在现有代码库中有auto_ptr,那么当您有机会时 尝试将auto_ptr全局搜索和替换为unique_ptr;该 绝大多数用途都是相同的,它可能会暴露(作为一个 编译时错误)或修复(默默地)你不了解的一两个错误 了。
换句话说,虽然全球搜索和替换可能会破坏&#34;暂时你的代码,你应该这样做:修复编译错误可能需要一些时间,但从长远来看会为你节省更多的麻烦。