Matrix of unique_ptr



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,因为它更安全,除非性能成为一个问题。

最新更新