std::auto_ptr 到 std::unique_ptr

问题描述 投票:0回答:4

随着新标准的到来(以及某些编译器中已经可用的部分),新类型

std::unique_ptr
应该是
std::auto_ptr
的替代品。

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

另外,如果是直接替换,为什么要给它一个新名称而不是仅仅改进

std::auto_ptr

c++ c++11 smart-pointers auto-ptr unique-ptr
4个回答
241
投票

您无法进行全局查找/替换,因为您可以复制

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


107
投票

std::auto_ptr
std::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
的奇怪行为,那么无论如何您都需要重构您的代码。
    


42
投票
GotW #89

有很好的解释:

auto_ptr 是怎么回事?

auto_ptr 最仁慈的特征是在 C++ 之前创建 unique_ptr 的勇敢尝试 具有移动语义。 auto_ptr 现已弃用,不应使用 在新代码中。 如果现有代码库中有 auto_ptr,当您有机会时 尝试进行全局搜索并将 auto_ptr 替换为 unique_ptr;这 绝大多数用途都会以相同的方式工作,并且它可能会暴露(作为 编译时错误)或修复(默默地)一两个你不知道的错误 有。

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


37
投票
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

将具有全新的功能:它们可以存储在容器中。

    

© www.soinside.com 2019 - 2024. All rights reserved.