std :: auto_ptr到std :: unique_ptr


185

随着新标准的到来(以及某些编译器中已有的部件),新类型std::unique_ptr应被替换为std::auto_ptr

它们的用法是否完全重叠(因此我可以在我的代码上进行全局查找/替换(不是我可以这样做,但是如果可以的话))还是应该注意阅读文档后看不到的一些区别?

另外,如果它是直接替代品,为什么给它起一个新的名字而不是仅仅改善它std::auto_ptr

Answers:


219

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

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


101
另一方面,执行此查找/替换操作只会导致编译错误,据我所知,它不会默默地破坏代码。因此,如果您随后手动修复编译错误,这是安全的
jalf

7
@jalf:的确,我想不出一个反例,该反例将通过auto_ptrs和UB与unique_ptrs一起很好地定义。
库比(Cubbi)2010年

1
因此,似乎unique_ptr是对auto_ptr的增强:支持数组并消除歧义
Baiyan Huang 2012年

92

std::auto_ptrstd::unique_ptr在someways和更换其他的下降不兼容。因此,没有找到/替换还不够好。但是,在查找/替换完所有编译错误之后,除了怪异的极端情况外,其他所有内容都应得到修复。大多数编译错误都需要添加std::move

  • 函数作用域变量:
    100%兼容,只要您不按值将其传递给另一个函数。
  • 返回类型:
    不是100%兼容,但99%兼容似乎没有错。
  • 按值的函数参数:
    100%与一个警告兼容,unique_ptr必须通过std::move调用传递s 。这很简单,如果编译不正确,编译器会抱怨。
  • 参考功能参数:
    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的奇怪行为,那么无论如何您都需要重构代码。


8
为“您仍然需要重构代码” +1。auto_ptrs仅适用于20.4.5 / 3所说的优点。
库比(Cubbi)2010年

8
让我补充一点,您应该在代码中以所有方式将auto_ptr替换为unique_ptr并修复编译错误。您会惊讶地发现会有多少个错误。
Bartosz Milewski 2010年

36

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将具有全新的功能:它们可以存储在容器中。


8
斯科特·迈耶斯(Scott Meyers)在他的“有效C ++”(第3版)第13项(第64页)中还提到,STL容器要求其内容具有“正常”复制行为,因此auto_ptr不允许使用。
徐强

31

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

auto_ptr有什么问题?auto_ptr的最大特点是在C ++具有移动语义之前尝试创建unique_ptr。auto_ptr现在已被弃用,不应在新代码中使用。

如果现有代码库中有auto_ptr,则当您有机会尝试对auto_ptr进行全局搜索和替换为unique_ptr时;绝大多数的用法都是一样的,并且可能会暴露(作为编译时错误)或(静默地)修复您不知道的一两个错误。

换句话说,尽管全局搜索和替换可能会暂时“破坏”您的代码,但您还是应该这样做:修复编译错误可能会花费一些时间,但从长远来看会为您节省很多麻烦。


很棒的链接。非常感谢!
fotNelton
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.