我使用std::vector
来存储一些对象数组,这些对象是由其他对象从向量外部引用的。我画了一个图表来更清楚地解释:
出于性能原因,我存储的是对象而不是指针。这些对象在我的游戏的每一帧都被排序,所以我希望数组具有良好的缓存属性。
当然,每当将对象添加到向量时,阵列都有可能被重置。在这种情况下,我的引用无效,需要更新。现在,为了检测重新安装,我使用以下方法:
size_t old_capacity = v.capacity();
// Do stuff that could change the vector's size
v.push_back(a);
v.push_back(b);
v.push_back(c);
if (old_capacity != v.capacity()) {
update_references();
}
我的问题是:
pop_back
后,我还需要检查重新安装吗?答案 0 :(得分:2)
在我看来,最好的方法如下:只需使用指向矢量头部的指针即可。并非所有重新分配都会导致向量移动。
但是,我或多或少同意有关向量中引用的注释。此外,您可以使用std :: list,它不会出现重新分配的问题。
std::vector<int> v;
void *old_location = (void *) &(v.front());
v.push_back(3);
v.push_back(3);
v.push_back(3);
if (old_location != &(v.front()))
update_references();
答案 1 :(得分:1)
正如您所正确指出的,每次向向量添加内容时,所有现有迭代器(和元素指针)都可能无效。虽然你可以尝试“检测”它,但我强烈建议以不同的方式解决问题。根据您的要求,您可以:
使用索引而不是直接指针。代替
您Obj* ptr
取消引用的*ptr
,
您将size_t idx
取消引用vector[idx]
。
如果你已经有许多使用指针的现有代码,你可以尝试创建一个智能指针,这将在幕后做。
如果添加,但永远不会从向量中删除项目,如果您不关心数据的连续性,则可能根本不想使用std::vector
!我认为类似于一个块列表,每个块 - 例如 - 一个256个对象的固定数组就足够了。您将拥有缓存局部性(因为块不小于缓存行)和相对便宜的动态可扩展性。实际上,如果你的数组变长,它可能会更快地执行向量,因为它永远不会重新分配内存。
如果您添加和删除项目,但是数据的排序和连续性很重要,您仍然可以使用块的列表,以及已删除对象的一些额外管理器,这将尝试在新的时候重用空白区域对象已添加。