为什么在标准容器中使用std::auto_ptr<>是错误的?
auto_ptr的复制语义与容器不兼容。
具体来说,将一个auto_ptr复制到另一个auto_ptr并不会创建两个相等的对象,因为其中一个已经失去了指针的所有权。
更具体地说,复制auto_ptr会导致其中一个副本放弃指针。这些元素中哪一个仍然保留在容器中没有定义。因此,如果将auto_ptrs存储在容器中,可能会随机失去对指针的访问。
STL容器需要能够复制存储在其中的项,并且被设计为期望原始和副本是等效的。自动指针对象有一个完全不同的契约,通过复制创建所有权的转移。这意味着auto_ptr容器将根据使用情况表现出奇怪的行为。
在Effective STL (Scott Meyers)第8项中有关于可能出错的详细描述,在Effective c++ (Scott Meyers)第13项中也有不那么详细的描述。
c++标准规定STL元素必须是“可复制构造的”和“可赋值的”。换句话说,一个元素必须能够被赋值或复制,并且这两个元素在逻辑上是独立的。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智能指针或boost等价物(如果你没有c++ 11)。下面是这些智能指针的boost库文档。
c++ 03标准(ISO-IEC 14882-2003)在第20.4.5条第3段中说:
[…] 【注:[…] auto_ptr不满足标准库的CopyConstructible和Assignable要求 容器元素,从而实例化标准库容器 使用auto_ptr会导致未定义的行为。-结束注]
c++ 11标准(ISO-IEC 14882-2011)在附录D.10.1第3段中规定:
[…] 注意:[…auto_ptr实例满足 MoveConstructible和MoveAssignable,但不符合要求 CopyConstructible和CopyAssignable。-结束注]
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代码可能无法在此编译 国际标准。
推荐文章
- 找出质数最快的算法是什么?
- c++枚举类可以有方法吗?
- 格式化IO函数(*printf / *scanf)中的转换说明符%i和%d之间的区别是什么?
- 将析构函数设为私有有什么用?
- main()中的Return语句vs exit()
- 为什么c#不提供c++风格的'friend'关键字?
- 在函数的签名中添加关键字
- 我如何在Visual Studio中预处理后看到C/ c++源文件?
- 为什么在标准容器中使用std::auto_ptr<>是错误的?
- 用比较double和0
- 保护可执行文件不受逆向工程的影响?
- 在c++中字符串前面的“L”是什么意思?
- 为什么std::map被实现为红黑树?
- 空括号的默认构造函数
- 做独一无二的完美转发