std :: auto_ptr到std :: unique_ptr

时间:2010-08-10 16:17:46

标签: c++ c++11 smart-pointers auto-ptr unique-ptr

随着新标准的出现(以及某些编译器中已有的部分),新类型std::unique_ptr应该是std::auto_ptr的替代品。

他们的用法是否完全重叠(所以我可以对我的代码进行全局查找/替换(不是我会这样做,但如果我这样做))或者我应该注意一些在阅读时不明显的差异文档?

此外,如果它是直接替换(为什么要给它一个新名称),而不仅仅是改进std::auto_ptr

4 个答案:

答案 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_ptrstd::unique_ptr在某些方面不兼容,而在其他方面则有所取代。所以,没有找到/替换不够好。然而,在通过编译错误进行查找/替换之后,应该修复除了奇怪的角落情况之外的所有内容。大多数编译错误都需要添加std::move

  • 功能范围变量:
    100%兼容,只要您不通过值传递给另一个函数。
  • 返回类型:
    不是100%兼容但99%兼容似乎没有错。
  • 按值计算的功能参数:
    100%兼容一个警告,unique_ptr必须通过std::move电话。这个很简单,因为如果你做不对,编译器会抱怨。
  • 参考功能参数:
    100%兼容。
  • 班级成员变量:
    这个很棘手。 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;暂时你的代码,你应该这样做:修复编译错误可能需要一些时间,但从长远来看会为你节省更多的麻烦。