C++ 为什么在标准容器中使用 std::auto_ptr<> 是错误的?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/111478/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 12:55:16  来源:igfitidea点击:

Why is it wrong to use std::auto_ptr<> with standard containers?

c++stlraiiauto-ptrc++-faq

提问by Uhall

Why is it wrong to use std::auto_ptr<>with standard containers?

为什么std::auto_ptr<>与标准容器一起使用是错误的?

采纳答案by Kevin

The C++ Standard says that an STL element must be "copy-constructible" and "assignable." In other words, an element must be able to be assigned or copied and the two elements are logically independent. std::auto_ptrdoes not fulfill this requirement.

C++ 标准规定 STL 元素必须是“可复制构造的”和“可赋值的”。换句话说,一个元素必须能够被分配或复制,并且这两个元素在逻辑上是独立的。std::auto_ptr不满足这个要求。

Take for example this code:

以这段代码为例:

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.

To overcome this limitation, you should use the std::unique_ptr, std::shared_ptror std::weak_ptrsmart pointers or the boost equivalents if you don't have C++11. Here is the boost library documentation for these smart pointers.

为了克服这个限制,如果您没有 C++11 ,您应该使用std::unique_ptr,std::shared_ptrstd::weak_ptr智能指针或 boost 等价物。 这是这些智能指针的 boost 库文档。

回答by Frank Krueger

The copy semanticsof auto_ptrare not compatible with the containers.

拷贝语义auto_ptr不与容器兼容。

Specifically, copying one auto_ptrto another does not create two equal objects since one has lost its ownership of the pointer.

具体来说,将一个复制auto_ptr到另一个不会创建两个相等的对象,因为一个对象已经失去了指针的所有权。

More specifically, copying an auto_ptrcauses one of the copies to let go of the pointer. Which of these remains in the container is not defined. Therefore, you can randomly lose access to pointers if you store auto_ptrsin the containers.

更具体地说,复制一个auto_ptr会导致其中一个副本放开指针。未定义哪些保留在容器中。因此,如果您存储auto_ptrs在容器中,您可能会随机失去对指针的访问权限。

回答by Lazer

Two super excellent articles on the subject:

关于这个主题的两篇超级优秀的文章:

回答by Garth Gilmour

The STL containers need to be able to copy the items you store in them, and are designed to expect the original and the copy to be equivalent. auto pointer objects have a completely different contract, whereby copying creates a transfer of ownership. This means that containers of auto_ptr will exhibit strange behaviour, depending on usage.

STL 容器需要能够复制您存储在其中的项目,并且旨在预期原始和副本是等效的。自动指针对象有一个完全不同的契约,由此复制创建了所有权的转移。这意味着 auto_ptr 的容器将表现出奇怪的行为,具体取决于使用情况。

There is a detailed description of what can go wrong in Effective STL (Scott Meyers) item 8 and also a not-so-detailed description in Effective C++ (Scott Meyers) item 13.

在 Effective STL (Scott Meyers) 第 8 项中详细描述了可能出错的地方,在 Effective C++ (Scott Meyers) 第 13 项中也有一个不太详细的描述。

回答by Dustin Getz

STL containers store copies of contained items. When an auto_ptr is copied, it sets the old ptr to null. Many container methods are broken by this behavior.

STL 容器存储包含项目的副本。复制 auto_ptr 时,它将旧 ptr 设置为 null。许多容器方法都被这种行为破坏了。

回答by bitek

C++03 Standard (ISO-IEC 14882-2003)says in clause 20.4.5 paragraph 3:

C++03 标准 (ISO-IEC 14882-2003)在第 20.4.5 条第 3 段中说:

[...] [Note: [...] auto_ptr does not meet the CopyConstructible and Assignable requirements for Standard Library container elements and thus instantiating a Standard Library container with an auto_ptr results in undefined behavior. — end note]

[...] [注意:[...] auto_ptr 不满足标准库容器元素的 CopyConstructible 和 Assignable 要求,因此使用 auto_ptr 实例化标准库容器会导致未定义的行为。— 尾注]

C++11 Standard (ISO-IEC 14882-2011)says in appendix D.10.1 paragraph 3:

C++11 标准 (ISO-IEC 14882-2011)在附录 D.10.1 第 3 段中说:

[...] Note: [...] Instances of auto_ptr meet the requirements of MoveConstructible and MoveAssignable, but do not meet the requirements of CopyConstructible and CopyAssignable. — end note ]

[...] 注意: [...] auto_ptr 的实例满足MoveConstructible 和MoveAssignable 的要求,但不满足CopyConstructible 和CopyAssignable 的要求。— 尾注 ]

C++14 Standard (ISO-IEC 14882-2014)says in appendix C.4.2 Annex D: compatibility features:

C++14 标准 (ISO-IEC 14882-2014)在附录 C.4.2 Annex D 中说:兼容性特性:

Change: The class templates auto_ptr, unary_function, and binary_function, the function templates random_shuffle, and the function templates (and their return types) ptr_fun, mem_fun, mem_fun_ref, bind1st, and bind2nd are not defined.
Rationale: Superseded by new features.
Effect on original feature: Valid C ++ 2014 code that uses these class templates and function templates may fail to compile in this International Standard.

更改:类模板 auto_ptr、unary_function 和 binary_function、函数模板 random_shuffle 和函数模板(及其返回类型)ptr_fun、mem_fun、mem_fun_ref、bind1st 和 bind2nd 未定义。
基本原理:被新功能取代。
对原始特性的影响:使用这些类模板和函数模板的有效 C++ 2014 代码可能无法在本国际标准中编译。