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

时间:2020-03-06 14:30:39  来源:igfitidea点击:

为什么在标准容器中使用std :: auto_ptr &lt;>是错误的?

解决方案

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

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

更具体地说,复制" auto_ptr"会导致其中一个副本释放指针。这些容器中剩余的哪些未定义。因此,如果在容器中存储" auto_ptrs",则可能会随机失去对指针的访问。

STL容器必须能够复制我们存储在其中的项目,并且旨在使原始和副本具有相同的功能。自动指针对象具有完全不同的契约,由此复制将创建所有权转移。这意味着auto_ptr的容器将表现出奇怪的行为,具体取决于用法。

在有效的STL(Scott Meyers)项目8中有可能出错的详细描述,在有效的C ++(Scott Meyers)项目13中没有那么详细的描述。

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

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.

为了克服这个限制,如果没有C ++ 11,则应使用std :: unique_ptr,std :: shared_ptr或者std :: weak_ptr智能指针或者boost等效项。这是这些智能指针的Boost库文档。

关于该主题的两篇超优秀文章:

  • 智能指针-什么,为什么,哪个?
  • 本周最佳专家#25