C++ 什么时候使用共享指针的向量,什么时候只使用普通对象的向量?

C++ 什么时候使用共享指针的向量,什么时候只使用普通对象的向量?,c++,pointers,vector,C++,Pointers,Vector,我有一个简短的问题 我开始学习C++,并且总是使用向量和对象中的共享指针。或者至少是聪明的指针 我目前正在编写一个游戏,我在想为什么我会使用智能指针 假设我有一个游戏类,它有一个玩家向量 我想什么时候选择 矢量播放器,我想什么时候选择矢量 如果实体的状态不是在向量中访问,则使用共享的PTR。同样,如果你做了一个事件循环,像玩家这样的事件会与其他实体发生碰撞。您需要复制指针/引用,否则无法更改实体的状态 另一个重要的事情是,当实体死亡,但与该实体相关的事件未被处理时,该实体将从向量中删除。当您使用

我有一个简短的问题

<>我开始学习C++,并且总是使用向量和对象中的共享指针。或者至少是聪明的指针

我目前正在编写一个游戏,我在想为什么我会使用智能指针

假设我有一个游戏类,它有一个玩家向量

我想什么时候选择 矢量播放器,我想什么时候选择矢量

如果实体的状态不是在向量中访问,则使用共享的PTR。同样,如果你做了一个事件循环,像玩家这样的事件会与其他实体发生碰撞。您需要复制指针/引用,否则无法更改实体的状态

另一个重要的事情是,当实体死亡,但与该实体相关的事件未被处理时,该实体将从向量中删除。当您使用shared_ptr时,实体将继续存在,直到eventqueue中的事件被删除。当您将整个播放器存储在向量中时,如果向量更改其大小,则存储在事件对象中的指针将不再指向正确的实体。当您使用共享的ptr时,实体可以正常使用,即使它不再存在于向量中。但是最好在实体被删除的事件中使用std::weak_ptr,当它不存在时,weak_ptr可以检查指针是否是一个悬空指针,这意味着实体不存在,不需要处理任何事件

使用实体向量所在的级别/维度:当某个实体转到另一个级别时,该实体需要移动到该级别,复制整个结构不是最好的主意。所以最好的办法是使用一些指针类型,比如shared_ptr,但我建议std::move the shared_ptr,以减少引用计数开销。使用std::move,共享的ptr与原始ptr一样快

实体的虚拟类:当您在2D或3D世界中编写游戏时,如果要在向量中存储许多不同类型的实体,必须使用某些pointertype来引用对象,因为这些实体的大小可能不同

固定玩家数量:如果您正在编程一个具有固定玩家数量的游戏,如纸牌游戏,您不会移动玩家,也不会删除一个玩家,但是您可以设置一个标志来指示玩家已死亡,并且您不需要从向量中删除实体,最好的方法是使用std::vector

我认为,使用矢量中的共享ptr和事件中的弱ptr引用是管理实体的最佳方式。虽然弱\r更快的方法不能保持实体的内存处于活动状态,但每次都需要检查指针

一些伪代码
四种明显的情况是1在两个向量之间共享对象,不同于包含彼此对象副本的两个向量2多态对象的向量。3种情况,其中对象的生存期可能需要延长到引用它的向量的生存期之外。1-3的4种组合。@Peter对于2和3,我更喜欢独特的。当对象足够大/昂贵,只有当对象不可移动且实际上需要动态调整大小或重新排列对象时,您才不想在矢量调整大小或元素擦除时复制和销毁时,适当使用shared_ptr非常合适vector@Caleth-当然。然而,这个问题与共享ptr的使用有关。我列出了我会考虑使用SyrdY-PTR的案例。这就是像这样的一般性问题的问题-在决定使用哪个选项时有很多考虑因素,而不是绝对的你应该键入规则。@无用为什么你想要一个可复制但不可移动的对象?谢谢你的清晰解释!这对我帮助很大。
if(fixed count of players
            && there are no other entities
            && there are no virtual subclasses of Player) {
    class Player { ... };

    using player_collection = std::vector<Player>;
    using reference_to_player = Player*;
} else {
    class Entity { public: ... virtual ~Entity(); };
    class Player: public Entity { ... };

    using entity_collection = std::vector<std::shared_ptr<Entity>>;
    using reference_to_entity = std::weak_ptr<Entity>;
};