要添加到矢量的函数结束后,矢量将丢失对条目的引用
Vector losing reference to entries after function to add to vector finishes
我正在实现一个实体组件系统,当我试图将组件添加到实体时遇到了问题。这样做的结构如下:
下面将找到一个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;
}
}
}
上面只是一个助手函数,首先找到实体,然后它会调用下面的函数:
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];
}
}
}
最后,在实体内部,我们有这个功能:
void Entity::addComponent(Component& component)
{
m_componentVector.push_back(component);
}
实体被保存在EntityManager内部的向量中,作为堆栈上的普通对象创建。这与ComponentManager内部的Position组件相同。
我的目标是将所有组件保留在ComponentManager中,系统向ComponentManager请求以某种方式处理组件。我想为每个实体保留指针或引用,指向它所拥有的组件。
我的问题是,一旦Entity::addComponent()完成,m_componentVector向量就不再包含添加到它的Component,就像它正在脱离范围一样。我想问题出在我传递副本而不是推荐信的地方?我最初把参数作为指针,但一直在尝试修复它。
注释中的相关事实:Entity::m_componentVector
被定义为
std::vector<Component> m_componentVector;
这是一个存储Component
对象而非引用的向量。因此,在Entity::addComponent
中,线
m_componentVector.push_back(component);
将复制component
引用的对象并将其添加到向量中。此副本独立于从中复制的对象。
更糟糕的是,addComponent
的component
参数实际上引用了PositionComponent
类型的对象(可能是从Component
派生的)。在进行上述复制时,将只复制与基类Component
相对应的部分。这被称为切片-派生类添加的部分被简单地"切片"。
您希望使实体的m_componentVector
引用存储在ComponentManager
中的组件。不能将引用存储在向量中。您可以存储指针,但如果向向量中添加了其他元素,指向向量元素的指针可能会无效(也就是说,如果您存储了指向m_positionComponentVector[0]
的指针,后来又向m_positionComponentVector
添加了更多元素,因此需要重新分配,则存储的指针将变为无效)。因此,存储索引是最安全的选择。
- CMake VS_PACKAGE_REFERENCES不添加对 VS2017 项目的引用
- 将新元素添加到列表中,并返回对该元素的引用?
- 本机 Nuget 包安装在 VS 中,但没有为C++(本机)项目添加引用
- 将常量添加到引用
- 为什么在此 CRTP 基函数调用中添加引用会消除错误?
- 在 ONE 设置中添加附加包含目录并引用 => 指向静态库
- 在C++中向地图添加对对象的引用
- 对成员变量的引用在向同一向量中添加另一个实例后断开
- 是否有一种方法可以将C 类成员引用到向量而不明确添加它们
- 处理受向 std::vector 添加元素影响的引用
- 如何将非托管库引用添加到 NUnit 测试
- 为什么添加对右值引用的引用不是错误
- 当通过引用传递时,通过传递链表在第n个位置添加元素不起作用
- 在 CMake CMakeLists.txt 中添加对 NewT 的库引用
- 添加到字符串数组和引用
- 添加了对 .lib 项目的引用 - 项目不使用.cpp文件
- 为什么Qt会向相对不被引用的库添加'PWD'?
- 添加控制器引用/指向c++单例类的指针
- 将函数引用添加到列表中
- Visual C# - 引用 > 添加引用... > COM:该列表是如何填充的?