unique_ptr
放入数组是否被认为是一种好习惯?是的,我知道,它们有不寻常的复制语义,但我的想法是:
我有一个基于平铺的游戏场。数组中的每个指针都指向某个游戏对象。当我为数组元素分配新的东西时,前一个对象被销毁并放置一个新对象。
另一个问题——shared_ptr 也一样,因为有时我会使用享元模式。
unique_ptr
的最大优势之一是在标准容器中使用是安全的,例如std::vector
. std::vector<std::unique_ptr<T>>
不是反模式,它非常好,强烈推荐。
一般来说,是的,这是一种很好的做法:在这种情况下,矩阵将是对象的所有者(在大多数情况下应该可以正常工作),而对象的其他消费者仅保留指向对象的原始指针(如果有的话)。
这是安全有效的。
另一方面,考虑是否需要指针。如果我理解正确,这里使用指针的唯一原因是能够存储多态对象。考虑是否boost::variant
可能是这里的替代方案,或者某种value_ptr
(不幸的是不包含在标准库中,但易于实现)。
;的复制语义没有什么不寻常的地方unique_ptr
。它们可以移动但不能复制,因此完全适合在标准容器中使用。
您可能会想到已弃用auto_ptr
的,在将移动语义添加到语言之前,它试图使用破坏性复制语义来模拟它们。这使得它们很难安全地与标准容器一起使用。
您是否应该在容器中存储指针或对象是另一个问题。一般来说,存储对象比较好;除非它们非常大或移动起来很昂贵,或者除非您需要存储(指向公共基类的指针)不同类型的对象。
如果您确实想存储指针,并且希望容器管理对象的生命周期,那么unique_ptr
是最好的选择。shared_ptr
如果您想与其他实体共享所有权,或者如果您想用于weak_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 因为它更安全,除非性能成为问题。