为什么这是错误的使用标准::auto_ptr<>与标准集装箱?
题
为什么这是错误的使用 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代码可能无法在此编译 国际标准。