你何时会使用共享指针的向量,何时使用普通对象的向量?

时间:2018-01-02 11:44:28

标签: c++ pointers vector

我有一个简单的问题。

我不久前开始学习C ++,并且总是使用带有共享对象指针的向量。或者至少是智能指针。

我正在编写一个游戏,我在考虑为什么要使用智能指针。

假设我有一个Game类,它有一个玩家矢量。

我希望何时选择 vector<Player> players以及何时选择vector<shared_ptr<Player>>

1 个答案:

答案 0 :(得分:0)

  1. 如果访问实体的状态而不是向量,请使用shared_ptr s。此外,如果您使用“玩家与其他实体相撞”等事件进行事件循环。您需要复制指针/引用,否则您无法更改实体的状态。

  2. 另一个重要的事情是,当实体死亡但未处理实体的事件时,将从矢量中删除该实体。当您使用shared_ptr时,实体会继续存在,直到事件队列中的事件被删除。当您将整个播放器存储在向量中时,如果向量更改其大小,则存储在event-object中的指针不再指向正确的实体。当您使用shared_ptr时,即使实体不再存在,也可以正常使用该实体。但最好在事件中使用std::weak_ptr,删除实体,当它死了,weak_ptr可以检查指针是否是悬空指针,这意味着实体已经死亡,没有事件需要待处理。

  3. 使用级别/维度,其中实体的向量存在:当某个实体进入另一个级别时,实体需要移动到该级别,复制整个结构不是最好的主意。所以最好的想法是使用像shared_ptr这样的指针类型,但我建议std::move使用shared_ptr来减少引用计数开销。使用std::move,shared_ptr与原始ptr一样快。

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

  5. 修正了玩家数量:如果您正在使用固定数量的玩家(如纸牌游戏)编写游戏,则不会移动玩家,也不会删除玩家(但是您可以设置一个表示玩家已死的标志,你不需要从向量中删除实体),最好的方法是使用std::vector<Player>

  6. 我认为,使用shared_ptr生活在向量中并使用weak_ptr引用事件是管理实体的最佳方式。虽然weak_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>;
    };
    
相关问题