为什么这是错误的使用 std::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。 以下是这些智能指针的升级库文档。

其他提示

auto_ptr 复制语义与容器不兼容。

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

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

两个超级优秀的文章的主题:

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

详细描述了有效STL(Scott Meyers)第8项中可能出现的问题,以及Effective C ++(Scott Meyers)第13项中的不详细描述。

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

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

  

[...]   [注意:[...]   auto_ptr不符合标准库的CopyConstructible和Assignable要求   容器元素,从而实例化标准库容器   使用auto_ptr导致未定义的行为。 &#8212;结束说明]

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

  

[...]   注意:[...] auto_ptr的实例符合要求   MoveConstructible和MoveAssignable,但不符合要求   CopyConstructible和CopyAssignable。 &#8212;尾注]

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代码可能无法在此编译   国际标准。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top