提问人:Uhall 提问时间:9/22/2008 最后编辑:Lightness Races in OrbitUhall 更新时间:3/31/2017 访问量:49578
为什么将 std::auto_ptr<> 与标准容器一起使用是错误的?
Why is it wrong to use std::auto_ptr<> with standard containers?
答:
的复制语义与容器不兼容。auto_ptr
具体来说,将一个对象复制到另一个对象不会创建两个相等的对象,因为其中一个对象已经失去了对指针的所有权。auto_ptr
更具体地说,复制会导致其中一个副本放弃指针。哪些保留在容器中未定义。因此,如果存储在容器中,则可能会随机失去对指针的访问权限。auto_ptr
auto_ptrs
STL 容器需要能够复制存储在其中的项目,并且设计为期望原始容器和副本是等效的。自动指针对象具有完全不同的约定,通过该约定,复制将创建所有权转移。这意味着auto_ptr容器将表现出奇怪的行为,具体取决于使用情况。
在有效 STL (Scott Meyers) 第 8 项中有关于可能出错的详细描述,在有效 C++ (Scott Meyers) 第 13 项中也有不太详细的描述。
STL 容器存储所包含项目的副本。复制auto_ptr时,它会将旧的 ptr 设置为 null。许多容器方法都因此行为而中断。
评论
unique_ptr
std::move(sourceObject)
auto_ptr
C++标准规定STL元素必须是“可复制构造的”和“可分配的”。换句话说,一个元素必须能够被赋值或复制,并且这两个元素在逻辑上是独立的。 不满足此要求。std::auto_ptr
以以下代码为例:
class X
{
};
std::vector<std::auto_ptr<X> > vecX;
vecX.push_back(new X);
std::auto_ptr<X> pX = vecX[0]; // vecX[0] is assigned NULL.
若要克服此限制,应使用 std::unique_ptr、std::shared_ptr 或
std
::weak_ptr
智能指针,如果没有 C++11,则应使用 boost 等效指针。以下是这些智能指针的 boost 库文档。
评论
unique_ptr
还不允许复制,因此某些 STL 操作将无法正常工作,除非它们可以使用其移动语义。
std::unique_ptr
unique_ptr
auto_ptr
auto_ptr
unique_ptr
reset
release
reset
release
auto_ptr
unique_ptr
关于该主题的两篇超级优秀的文章:
评论
auto_ptr
sort()
C++ 标准 (ISO-IEC 14882-2003) 在第 20.4.5 条第 3 款中说:
[...] [注意:[...] auto_ptr 不符合标准库的 CopyConstructible 和 Assignable 要求 容器元素,从而实例化标准库容器 auto_ptr会导致未定义的行为。— 结束语]
C++ 标准 (ISO-IEC 14882-2011) 在附录 D.10.1 第 3 段中说:
[...]注意:[...]auto_ptr实例满足以下要求 MoveConstructible 和 MoveAssignable,但不符合要求 的 CopyConstructible 和 CopyAssignable。— 尾注 ]
C++14标准(ISO-IEC 14882-2014)在附录C.4.2中说 附件D:兼容性特点:
更改:类模板 auto_ptr、unary_function 和 binary_function,函数模板random_shuffle,以及 函数模板(及其返回类型) ptr_fun、mem_fun、 mem_fun_ref、bind1st 和 bind2nd 未定义。
基本原理:被新功能取代。
对原始功能的影响:使用这些类模板和函数模板的有效 C++ 2014 代码可能无法在此编译 国际标准。
评论
move
语义,旨在避免与 相关的问题。在 C++ 03 中,该语言不够强大,无法编写在所有场景中都正确安全地运行的类,因为编译器和语言无法区分 l 和 r 值,因此大多数时候使用一些“hack”来获得所需的行为。unique_ptr
auto_ptr
auto_ptr