为什么在标准容器中使用std :: auto_ptr <>是错误的?
时间:2020-03-06 14:30:39 来源:igfitidea点击:
为什么在标准容器中使用std :: auto_ptr <>
是错误的?
解决方案
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