向功能添加到矢量完成后失去对条目的引用的向量

时间:2014-08-27 22:48:52

标签: c++ entity-framework vector

我正在实现一个实体组件系统,当我尝试向实体添加组件时遇到了麻烦。这样做的结构如下:

下面会找到一个ID为0的实体,并为其添加一个位置组件。

m_entityManager->addComponentToEntityID(0, ComponentManager::POSITION);

void EntityManager::addComponentToEntityID(unsigned int entityID, ComponentManager::ComponentType componentType)
{
    std::shared_ptr<Entity> tempEntity;

    for (unsigned int index = 0; index < m_maximumEntities; ++index)
    {
        if (m_entityVector[index].getEntityID() == entityID)
        {
            addComponentToEntity(std::make_shared<Entity>(m_entityVector[index]), componentType);
            break;
        }
    }
}

以上只是首先找到Entity的辅助函数,然后它会调用下面的函数:

void EntityManager::addComponentToEntity(std::shared_ptr<Entity> entity, ComponentManager::ComponentType componentType)
{
    if (entity != nullptr)
    {
        switch (componentType)
        {
            case ComponentManager::POSITION:
                entity->addComponent(m_componentManager->getUnassignedPositionComponent());
                break;

    default:
        break;
        }
   }
}

此函数将找到未分配(免费,可用,未添加到实体)位置组件并将其返回。

PositionComponent& ComponentManager::getUnassignedPositionComponent()
{
    for (unsigned int index = 0; index < m_positionComponentVector.size(); ++index)
    {
        if (m_positionComponentVector[index].isAssigned() == false)
        {
            m_positionComponentVector[index].assign();
            return m_positionComponentVector[index];
        }
    }
}

最后,在Entity中我们有这个功能:

void Entity::addComponent(Component& component)
{
    m_componentVector.push_back(component);
}

实体保存在EntityManager内部的向量内,作为堆栈上的普通对象创建。对于ComponentManager内部的位置组件,这是相同的。

我的目标是将所有组件保留在ComponentManager和系统中,并向ComponentManager请求以某种方式处理组件。我想将每个实体的指针或引用保留到它拥有的组件中。

我的问题是,一旦Entity :: addComponent()完成,m_componentVector向量就不再保存添加到它的Component,就像它超出范围一样。我认为问题出在某个地方我传递副本而不是引用?我最初将参数作为指针,但正在尝试修复它。

1 个答案:

答案 0 :(得分:1)

评论中的相关事实:Entity::m_componentVector被定义为

std::vector<Component> m_componentVector;

这是一个存储Component个对象的向量,而不是引用。因此,在Entity::addComponent中,行

m_componentVector.push_back(component);

将复制component引用的对象并将其添加到向量中。此副本独立于从。复制的对象。

更糟糕的是,component addComponent参数实际上引用了PositionComponent类型的对象(可能是Component派生的)。在制作上述副本时,只会复制与基类Component对应的部分。这被称为切片 - 派生类添加的部分只是&#34;切掉&#34;。

您希望让实体m_componentVector引用ComponentManager中存储的组件。您无法在向量中存储引用。您可以存储指针,但是如果向向量添加了其他元素(即,如果存储指向m_positionComponentVector[0]的指针),则可以使指向向量元素的指针无效,并且稍后会向m_positionComponentVector添加更多元素。如果需要重新分配,您存储的指针将变为无效)。因此,存储指数是您最安全的选择。