对象向量中的空对象与指针向量中的NULL/nullptr

Empty Objects in a Vector of Objects vs NULL/nullptr in a Vector of Pointers

本文关键字:对象 向量 nullptr NULL 指针      更新时间:2023-10-16

我正在尝试创建一种实体/组件系统,其中唯一标识实体的是组件向量的索引。

这应该是所谓实体组件系统的一种实现。这是我正在开发的一款游戏。

例如,有一个精灵组件向量和一个健康组件向量,它们上的相同索引是同一实体的一部分。即spriteComponents[0]与healthComponents[0]是同一实体的一部分。

我遇到的问题是,并不是所有实体都具有所有类型的组件。这意味着我必须在向量上推送某种空/null,实体的组件类型不必保持index=entity-id系统的完整性。

即实体1(索引1)没有spriteComponents,因此spriteComponents[1]应该是某种类型的空/null。

例如:

带有空对象/空指针:
组件类型1:[x][x][x]
组件类型2:[x][0][x]

无:
组件类型1:[x][x][x]
组件类型2:[x][x]

没有它们,索引将无法正常工作。

现在我有两个选择,都应该有效,但我想知道哪种方式更好:

//Option 1:
std::vector<SpriteComponent> spriteComponents;
/*Add empty object to retain index = entity system
when entity does not have a particular component*/
spriteComponents.push_back(SpriteComponent());
//Option 2:
std::vector<std::shared_ptr<SpriteComponent>> spriteComponents;
/*Add nullptr to retain index = entity system
when entity does not have a particular component*/
spriteComponents.push_back(nullptr);

据我所知,选项1的优点是对象在内存中是连续的,但使用空对象似乎不太理想。这是否仍然比使用可以简单使用nullptr/NULL的指针更可取?

当然,如果有更好的选择,我愿意接受建议。

编辑:
-我计划的实体不是实际对象,即实体只是向量的索引。这样,以后的系统(如绘图)就可以简单地遍历包含精灵组件的向量,而不必关心它们是谁的精灵。

这应该是相当有效的,因为它们在内存中紧挨着,而在一个系统中,Entity是一个包含spriteComponent和healthComponent等的类。迭代的效率会大大降低(或者据我所知),因为类似的组件在内存中可能根本就不在一起。

实际上,让实体作为一个只包含必要索引的对象存在可能是一个可行的解决方案。然后我也可以让它们包含一个数字,告诉它实际上有什么组件和没有什么组件。

-实体之间不会共享组件。

-healthComponent只是一个组件的例子,但它将包含有关实体健康状况的信息和影响健康状况的消息(healthpoints、armorclass等)。我正在考虑将它们简单地作为structs(components)

谢谢。

您可能需要查看boost::optional