C ++容器和右侧

时间:2012-09-13 08:09:44

标签: c++ pointers containers

我今天读到你不应该使用STL容器来获取auto_ptr因为 auto_ptr删除了=运算符中的rhs值。

所以我有两个问题:

1)这是否意味着所有具有此行为的类不应在容器中使用?

2)你可以使用哪种容器?

3 个答案:

答案 0 :(得分:3)

  

1)这是否意味着所有具有此行为的类都不应该   在容器中使用?

确实如此,因为这不是正确的复制行为,因为副本后来不等于源,但会破坏源。这是在C ++ 11之前对move-semantics的一种破坏实现,是std::auto_ptr的严格唯一所有权语义所必需的。

  

2)你可以使用哪种容器?

实际上,答案是,具有此行为的类(复制构造函数/赋值销毁其源)应该不存在。幸运的是,现在不再需要这样了,因为C ++ 11具有适当的移动语义,它可以以一种安全的方式实现这种破坏性的复制(简单地说,只有当不再需要源时)。

因此,std::auto_ptr已弃用,不应再使用。它已由std::unique_ptr取代,std::unique_ptr可移动但不可复制。但是,由于C ++ 11容器在适当时移动元素而不是复制,因此std::unique_ptr可以在标准容器内完美使用。你只是不能复制容器或用一个需要std:auto_ptr的副本的单个对象填充它,但这些操作无论如何都不应该工作,因为它们在概念上对于唯一所有权语义是错误的。

作为旁注,如果你真的选择std::shared_ptr是因为某种原因,那就是你想要独特的所有权语义,那么std::unique_ptr(正如其他答案所建议的那样)是完全错误的,因为它展示了共享所有权。 std::auto_ptr今天是std::shared_ptr。永远不要将std::unique_ptr s {{1}} s(或者甚至是原始指针,但是从我的问题中我判断该选项出来)发送到适当的地方。

答案 1 :(得分:2)

自动指针具有非常严格的所有权:它只负责它指向的对象的生命周期。如果您复制auto_ptr,则会丢失对其指向的引用。

问题在于STL容器的用途。例如,当您添加元素时,容器可能会扩展以获得更多内存,从而导致将所有值复制到新内存,这本身会导致丢失auto_ptrs。

认为关联容器在分配额外内存时可能无法完全复制自己,但我绝对不确定,如果有人可以确认,请发表评论,或者只是编辑我的回答。无论如何,你最好不要冒险。

另请注意,自C ++ 0x以来,Auto_ptr已被弃用,建议使用unique_ptr代替std::shared_ptr。在你的情况下,{{1}}可能会做到这一点,除非你真的需要对你的那些对象拥有独特的所有权。

答案 2 :(得分:2)

完全。 通常,序列容器元素必须是CopyConstructible和Assignable。这意味着他们需要:

  • 公共副本构造函数
  • 公共任务运营商

Asociative容器(set&lt;&gt;和map&lt;&gt;)也必须提供严格的弱排序,即必须定义operator <(或专用的比较函数)。

C ++标准的第23.1章提供了详细的要求。