将unique_ptr
放在数组中被认为是好的做法吗?是的,我知道,它们具有不寻常的复制语义,但我的想法是这样的:
我有一个基于平铺的游戏场地。数组中的每个指针都指向某个游戏对象。当我为数组元素分配新内容时,将销毁以前的对象并放置一个新对象。
另一个问题 - 关于shared_ptr也是如此,因为有时我会使用蝇量级模式。
unique_ptr
最大的优点之一是它可以安全地用于像 std::vector
这样的标准容器中。 std::vector<std::unique_ptr<T>>
不是反模式,它非常好,强烈推荐。
一般来说,这是很好的做法:在这种情况下,矩阵将是对象的所有者(在大多数情况下应该运行良好),而对象的其他使用者只是保留指向对象的原始指针,如果有的话。
这是安全有效的。
另一方面,考虑是否需要指针。如果我理解正确,在这里使用指针的唯一原因是能够存储多态对象。考虑一下boost::variant
在这里是否是一种替代方案,或者某种value_ptr
(不幸的是,标准库中不包含,但易于实现)。
unique_ptr
的复制语义没有什么不寻常的;它们可以被移动但不能复制,因此完全适合在标准容器中使用。
您可能正在考虑已弃用的auto_ptr
,在将移动语义添加到语言之前,它试图使用破坏性复制语义来模拟它们。这使得它们很难安全地与标准容器一起使用。
是否应该在容器中存储指针或对象是另一个问题。通常,最好存储对象;除非它们非常大或移动成本很高,或者除非您需要存储不同类型的对象(指向公共基类的指针)。
如果确实要存储指针,并希望容器管理对象的生存期,则unique_ptr
是最佳选择。 如果要与其他实体共享所有权,或者要使用weak_ptr
来确定对象是否已从数组中删除,则shared_ptr
也是合适的。
unique_ptr比shared_ptr性能更高,因为它不进行引用计数,但是一个地方必须拥有所有权。 这是有风险的,因为如果您有:
vector<unique_ptr<GameObject>> v;
您将引用它:
GameObject* p = v[42].get();
然后,如果位置 42 被删除或替换,P 将是一个悬挂指针。
然而:
vector<shared_ptr<GameObject>> v;
shared_ptr<GameObject> p = v[42];
即使删除 v[42],也会将底层对象保留在 p 周围 - 但你有引用计数更新的开销。
我的建议是更喜欢shared_ptr,因为它更安全,除非性能成为一个问题。