我理解auto_ptr已经搞砸了复制语义,因此在容器中使用是不安全的,因为将一个auto_ptr复制到另一个会使source = NULL指针(不管怎么说这就像移动语义一样?)。但话说再说一次,unique_ptr根本无法复制,只能转让所有权。那么,unique_ptr如何在需要使用复制操作来复制和重新排列元素的容器和算法中使用呢?
答案 0 :(得分:5)
有一个深入解释为什么auto_ptr
是危险的,而unique_ptr
则不是:
N1856 : Why deprecate auto_ptr?
主要论点是,在通用代码中,具有副本语法的东西应该是副本,而不是移动:
template <class It>
void sort(It first, It last)
{
// ...
value_type pivot_element = *mid_point;
// ...
}
在上面的示例中,通用代码很可能具有在显示复制结构后要求pivot_element
和*mid_point
等效的逻辑。这可能是也可能不是std::lib
中的通用代码。它可能是您编写的通用代码。
当value_type
变成std::auto_ptr<T>
时,上面的代码会编译,但假设pivot_element == *mid_point
失败。随后出现运行时错误。
当value_type
变成std::unique_ptr<T>
时,上述代码在编译时失败(因为您无法复制std::unique_ptr<T>
)。因此,优先使用std::unique_ptr<T>
优先于std::auto_ptr<T>
会将运行时错误转换为编译时错误。
现在,在std::lib
范围内,sort
等算法已被重新指定,因此不允许复制value_type
。因此,现在对auto_ptr<T>
序列进行排序实际上是安全的(使用std::sort
)。但是std::unique_ptr<T>
完全取代了auto_ptr<T>
的功能,而auto_ptr<T>
在确实使用复制的通用代码中仍然很危险(unique_ptr<T>
无效在这种通用代码中使用时编译。)
所以unique_ptr
使用比auto_ptr
更安全,因为它与复制的通用代码一起使用时拒绝编译。
答案 1 :(得分:0)
在绝大多数情况下,他们不再需要使用复制操作。像unique_ptr这样的仅移动类型是一等公民。这就是为什么移动语义在性能和正确性方面都是一个很大的改进。