std :: auto_ptr到std :: unique_ptr

Mar*_*ork 182 c++ smart-pointers auto-ptr unique-ptr c++11

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

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

此外,如果它是一个直接替代品(为什么给它一个新的名称),而不仅仅是改善std::auto_ptr.

Cub*_*bbi 214

您无法进行全局查找/替换,因为您可以复制auto_ptr(具有已知后果),但unique_ptr只能移动.任何看起来像

std::auto_ptr<int> p(new int);
std::auto_ptr<int> p2 = p; 
Run Code Online (Sandbox Code Playgroud)

必须至少成为这样的

std::unique_ptr<int> p(new int);
std::unique_ptr<int> p2 = std::move(p);
Run Code Online (Sandbox Code Playgroud)

至于其他差异,unique_ptr可以正确处理数组(它将调用delete[],而auto_ptr将尝试调用delete.

  • 另一方面,执行此查找/替换只会导致编译错误,就我所见,它不会默默地破坏代码.因此,如果您之后手动修复编译错误,那么这样做是安全的 (97认同)
  • @jalf:的确,我想不出一个反例,用auto_ptrs和UB用unique_ptrs定义好. (7认同)
  • 所以似乎 unique_ptr 是 auto_ptr 的增强:支持数组并消除歧义 (2认同)

def*_*ode 90

std::auto_ptr并且std::unique_ptr在某些方面是不相容的,而在其他方面则是替代品.所以,没有找到/替换不够好.然而,在通过编译错误进行查找/替换之后,应该修复除了奇怪的角落情况之外的所有内容.大多数编译错误都需要添加一个std::move.

  • 函数范围变量:
    100%兼容,只要您不通过值将其传递给另一个函数.
  • 返回类型:
    不是100%兼容但99%兼容似乎没有错.
  • 函数参数值:
    100%与一个警告兼容,unique_ptrs必须通过std::move调用传递.这个很简单,因为如果你没有把它弄好,编译器会抱怨.
  • 参考功能参数:
    100%兼容.
  • 类成员变量:
    这个很棘手. std::auto_ptr复制语义是邪恶的.如果班级不允许复制,那么std::unique_ptr就是替代品.但是,如果您尝试为该类提供合理的复制语义,则需要更改std::auto_ptr处理代码.这很简单,因为如果你没有把它弄好,编译器会抱怨.如果你允许复制一个没有任何特殊代码的std::auto_ptr成员的课程,那么你就会感到羞耻,祝你好运.

总之,std::unique_ptr是一个不间断的std::auto_ptr.它在编译时不允许使用a时经常出错的行为std::auto_ptr.因此,如果您使用std::auto_ptr所需的护理,切换到std::unique_ptr应该很简单.如果你依赖于std::auto_ptr奇怪的行为,那么无论如何你都需要重构你的代码.

  • +1"无论如何你需要重构你的代码".auto_ptrs只适用于20.4.5/3表示它们有用的东西. (8认同)
  • 让我补充一点,你应该通过各种方法在代码中用unique_ptr替换auto_ptr并修复编译错误.你会惊讶地发现有多少虫子会发现. (8认同)

Unc*_*ens 34

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
Run Code Online (Sandbox Code Playgroud)

另一方面,unique_ptr将具有全新的功能:它们可以存储在容器中.

  • Scott Meyers在他的"Effective C++"(第3版)第13项(第64页)中也提到STL容器要求其内容呈现"正常"复制行为,因此不允许使用"auto_ptr"容器. (7认同)

Val*_*ris 29

Herb Sutter对GotW#89有一个很好的解释:

与auto_ptr有什么关系?auto_ptr最为慈善的特征是在C++移动语义之前创建unique_ptr的勇敢尝试.auto_ptr现已弃用,不应在新代码中使用.

如果您在现有代码库中有auto_ptr,那么当您有机会尝试将auto_ptr全局搜索并替换为unique_ptr时; 绝大多数用途都是相同的,它可能会暴露(作为编译时错误)或修复(默默地)你不知道的一两个错误.

换句话说,虽然全局搜索和替换可能会暂时"破坏"您的代码,但您仍应该这样做:修复编译错误可能需要一些时间,但从长远来看会为您节省更多麻烦.