我今天读到你不应该为 auto_ptr 使用 STL 容器,因为 auto_ptr 在 = 运算符中删除了它的 rhs 值。
所以我有两个问题:
1)这是否意味着所有具有这种行为的类都不应该在容器中使用?
2)你可以使用什么样的容器?
我今天读到你不应该为 auto_ptr 使用 STL 容器,因为 auto_ptr 在 = 运算符中删除了它的 rhs 值。
所以我有两个问题:
1)这是否意味着所有具有这种行为的类都不应该在容器中使用?
2)你可以使用什么样的容器?
1)这是否意味着所有具有这种行为的类都不应该在容器中使用?
确实是的,因为这不是正确的复制行为,因为之后的副本不等于源,而是破坏了源。这是 C++11 之前移动语义的一种破碎实现,这是std::auto_ptr
.
2)你可以使用什么样的容器?
真正的答案实际上是,具有这种行为的类(复制构造函数/赋值破坏其源)不应该存在。幸运的是,现在不再需要这个了,因为 C++11 具有适当的移动语义,可以准确地实现这种破坏性复制,但以安全的方式(简单地说,只有当源真的不再需要时)。
因此std::auto_ptr
已弃用,不应再使用。它已被替换std::unique_ptr
为可移动但不可复制。但是由于 C++11 容器宁愿移动它们的元素而不是在适当的时候复制,所以 astd::unique_ptr
可以完美地在标准容器中使用。您只是不能复制容器或用需要std::unique_ptr
s 副本的单个对象填充它,但是这些操作无论如何都不应该起作用,因为它们在概念上对于唯一所有权语义是错误的。
附带说明一下,如果您实际上是std:auto_ptr
出于某种原因选择的,那就是您想要唯一的所有权语义,那么 a std::shared_ptr
(正如其他答案所建议的)是完全错误的,因为它表现出共享所有权。std::unique_ptr
是今天的std::auto_ptr
。永远不要垃圾邮件std::shared_ptr
s where std::unique_ptr
s (甚至是原始指针,但根据您的问题,我排除了该选项)是合适的。
自动指针有一个非常严格的所有权:它并且只有它负责它所指向的对象的生命周期。如果您复制一个auto_ptr
,您将失去对它所指向的内容的引用。
问题在于 STL 容器的工作方式。例如,当您添加一个元素时,容器可能会扩展以获得更多内存,这会导致将所有值复制到新内存中,这本身会导致丢失 auto_ptrs。
我认为关联容器在分配额外内存时可能不会完全复制自己,但我绝对不确定,如果有人可以确认,请发表评论,或者只是编辑我的答案。无论如何,你最好不要冒险。
另请注意,Auto_ptr
自 C++0x 以来已弃用,建议unique_ptr
改用。在您的情况下,std::shared_ptr
可能会成功,除非您确实需要您的这些对象的唯一所有权。
确切地。通常,序列容器元素必须是 CopyConstructible 和 Assignable。这意味着他们需要:
关联容器(set<> 和 map<>)也必须提供严格的弱排序,即operator <
必须定义(或专用的比较函数)。
C++ 标准的第 23.1 章提供了详细的要求。