Std::auto_ptr改为Std::unique_ptr

随着新标准的到来(部分标准已经在一些编译器中可用),新类型std::unique_ptr应该是std::auto_ptr的替代品。

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

另外,如果它是一个直接的替换,为什么给它一个新名字,而不是改进std::auto_ptr?

68460 次浏览

std::auto_ptrstd::unique_ptr在某些方面不兼容,在其他方面的替换量下降。所以,没有查找/替换是不够的。然而,在查找/替换之后,通过编译错误应该可以修复所有问题,除了奇怪的角落情况。大多数编译错误都需要添加std::move

    <李> 函数作用域变量: < br > 100%兼容,只要你不通过值传递给另一个函数 <李> 返回类型: < br > 不是100%兼容,但99%兼容似乎没有错 <李> 函数参数按值划分: < br > 与一个警告100%兼容,unique_ptrs必须通过std::move调用传递。这个很简单,因为如果你没有得到正确的编译器将报错 <李> 引用函数参数: < br > 李100%兼容。< / > <李> 类成员变量: < br > 这一点很棘手。std::auto_ptrs复制语义是邪恶的。如果类不允许复制,则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的奇怪行为,那么无论如何你都需要重构你的代码。

你不能做全局查找/替换,因为你可以复制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

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

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

auto_ptr是怎么回事? auto_ptr被最仁慈地描述为在c++之前创建unique_ptr的勇敢尝试 有移动语义。Auto_ptr现在已弃用,不应该使用 在新代码中。

如果你有auto_ptr在现有的代码库,当你有机会 尝试将auto_ptr全局搜索替换为unique_ptr;的 绝大多数的使用都是一样的,并且它可能会暴露(作为一个 编译时错误)或(默默地)修复一两个你不知道的错误 。< / p >

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