正确使用智能指针而不泄漏

Using smart pointers correctly without leaks

本文关键字:泄漏 指针 智能      更新时间:2023-10-16

我正在研究一个架构,在这个架构中,我需要在不同的列表中有一个实体,比如:

  • 渲染器->组件列表(SpriteComponent)
  • Collisioner->组件列表(PhysicComponent)

我认为智能指针是管理所有这些引用的最佳解决方案,所以我开始学习它,但我遇到了一些问题,我很怀疑我是否正确使用了它们。


说明:

我有一个抽象类:IEntity

class IEntity {
  public:
    IEntity( World& world );
  private:
    World* world;
  public:
    std::tr1::weak_ptr<IEntity> weak_this;
};
typedef std::tr1::shared_ptr<IEntity> Entity;

我有一个在EntityManager中创建实体的方法:

Entity EntityManager::createEntity() {
    Entity entity( new IEntity( *this->world ) );
    entity->weak_this = entity;
    this->entityList.add( &entity );
    return entity;
}

在我的EntityManager类中,我得到了一个"Entity"(of shared_ptr)的向量:

std::vector<Entity> entityList;

1-我是否需要在程序中的任何地方使用类型"实体"(在参数中,…)

2-如果我有这个:

class IComponent {
  public:
    IComponent();    
};
typedef std::tr1::shared_ptr<IComponent*> Component;

我有一个这样的物体:

class SpriteComponent : public Component {
  public:
    SpriteComponent();        
    int texture;
};

从shared_ptr继承很好吗?这对我来说很奇怪,但那确实有效。

3-我已经尝试使用这个创建10000个实体:

Entity entity = world.getEntityManager().createEntity();

对实体的引用是在我的"实体"向量中推送的,如果我真的理解了智能指针,清除向量会删除所有实体(因为没有其他引用)。但是,当我使用cXode泄漏探查器查看时,我可以看到在没有删除Entity的情况下内存在增长。所以我只是尝试在向量中插入来创建实体,但我没有泄漏,为什么?问题出在哪里?哦。

4-如果我在游戏中使用smart_ptr,我是否有一些性能问题?(我使用的是参考资料):

谢谢你抽出时间!

  1. 我不会称它为Entity,但可能是EntityPtr或类似的东西。(Entity表明它是IEntity的具体实现)
  2. 不要从Component派生,而是从IComponent派生。然后,您的Component智能指针将能够容纳SpriteComponent类型的对象
  3. 如果不存在其他引用,EntityManager.entityList上的清除将删除对象。但是,在填充向量时,您的代码似乎在做一些奇怪的事情。

    EntityPtr entity( new IEntity( *this->world ) );
    ...
    this->entityList.add( &entity );
    

    这会将实体的地址添加到实体列表中,那里不应该有&。我不知道为什么这会导致泄漏,但这绝对是错误的。

  4. 是的,使用智能指针会对性能造成影响。但在你把它作为核心循环中的一个问题来衡量之前,不要担心它——这可能永远都不够重要