假设我已经分配了一些内存并用一组相同类型的对象填充它,我们将调用这些组件。
假设需要删除其中一个组件,那么这样做的好方法是什么,以便可以通过循环遍历对象集来测试和跳过组件创建的“洞”?
反之亦然,我希望能够测试一个孔以便在空间中存储新组件。
我在想 menclear 并检查 0...
boost::optional<component>
似乎完全符合您的需求。把它们放在你的仓库里,不管是什么。例如,与std::vector
// initialize the vector with 100 non-components
std::vector<boost::optional<component>> components(100);
// adding a component at position 15
components[15].reset(component(x,y,z));
// deleting a component at position 82
componetnts[82].reset()
// looping through and checking for existence
for (auto& opt : components)
{
if (opt) // component exists
{
operate_on_component(*opt);
}
else // component does not exist
{
// whatever
}
}
// move components to the front, non-components to the back
std::parition(components.begin(), components.end(),
[](boost::optional<component> const& opt) -> bool { return opt; });
简短的回答是这取决于你如何将它存储在内存中。
例如,ansi 标准建议连续分配向量。
如果可以预测对象的大小,或许可以使用 size_of 和寻址等函数来预测内存中的位置。
祝你好运。
至少有两种解决方案:
1)用一些标志标记孔,然后在加工时跳过它。好处:'删除'非常快(只设置一个标志)。如果对象不是那么小,即使添加“bool alive”标志也不难做到。
2)在池的末端移动一个洞,并用一些“活”的物体代替它。
这个问题与存储和处理粒子系统有关,你可以在那里找到一些建议。
如果无法向上移动“活动”组件,或重新排序它们以使序列中间没有孔,那么最好的选择是给组件对象一个“已删除”标志/状态,可以通过成员函数测试。
这种“已删除”状态不会导致对象从内存中删除(这在较大块的中间是不可能的),但它确实可以将点标记为未用于组件。
当您说您“分配了一些内存”时,您可能是在谈论一个数组。数组很棒,因为它们几乎没有开销并且通过索引访问非常快。但是数组的坏处是它们对调整大小不是很友好。当您删除中间的元素时,所有后续元素都必须向后移动一个位置。
但幸运的是,您还可以使用其他数据结构,例如链表或二叉树,它们可以快速删除元素。C++ 甚至在容器类std::list和std::set中实现了这些。
当您事先不知道需要多少元素时,列表非常有用,因为它可以动态收缩和增长,而不会在您删除或添加任何元素时浪费任何内存。此外,添加和删除元素非常快,无论是在开头、结尾还是中间某个位置插入它们。
一组非常适合快速查找。当你有一个对象并且你想知道它是否已经在集合中时,检查它会非常快。集合还会自动丢弃重复项,这在许多情况下非常有用(当您需要重复项时,有std::multiset)。就像列表一样,它会动态适应,但添加新对象的速度不如列表快(尽管不像数组那样昂贵)。
两个建议:
1)您可以使用链接列表来存储您的组件,然后不用担心漏洞。
或者,如果您需要这些孔:
2)您可以将组件包装到一个带有指向组件的指针的对象中,如下所示:
class ComponentWrap : public
{
Component component;
}
并用于ComponentWrap.component == null
查找组件是否被删除。
异常方式:
3) 将代码放入 try catch 块中,以防遇到空指针错误。