繁体   English   中英

C ++容器和右侧

[英]C++ Containers and right hand side

今天,我读到您不应该将STL容器用于auto_ptr,因为auto_ptr会在=运算符中删除它的rhs值。

所以我有两个问题:

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

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

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

的确是这样,因为那是不正确的复制行为,因为此后复制并不等于源,而是破坏了源。 在C ++ 11之前,这是移动语义的一个残破实现,这对于std::auto_ptr的严格唯一所有权语义是必需的。

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

真正的答案实际上是,具有这种行为(复制构造函数/赋值会破坏其源代码)的类不应该存在。 幸运的是,由于C ++ 11具有适当的移动语义,因此如今已不再需要它,它可以安全地准确地实现此破坏性副本(简而言之,仅当确实不再需要该源时)。

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

附带说明一下,如果您实际上出于某种原因选择了std:auto_ptr ,那就是您想要唯一的所有权语义,那么std::shared_ptr (如其他答案所建议的那样)便是错误的,因为它表现出共享所有权。 std::unique_ptr是今天的std::auto_ptr 绝对不要发送垃圾邮件std::shared_ptr ,其中std::unique_ptr (甚至是原始指针,但从您的问题我可以排除该选项)是合适的。

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

问题在于STL容器的工作方式。 例如,当您添加一个元素时,容器可能会扩展以获取更多的内存,从而导致将所有值复制到新的内存中,从而导致丢失auto_ptrs。

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

另请注意,自C ++ 0x起已弃用Auto_ptr ,建议改用unique_ptr 在您的情况下, std::shared_ptr可能会解决问题,除非您确实确实需要这些对象的唯一所有权。

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

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

关联容器(set <>和map <>)也必须提供严格的弱排序,即必须定义operator < (或专用比较功能)。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM