我有一个相当复杂的场景,所以我试图将其提炼到基本问题。
我有3个课程(这里简化):
class Base {
protected:
std::map <unsigned int, Node*> nodes;
}
class Node {
protected:
std::map <unsigned int, Leaf*> leaves;
}
class Leaf {
protected:
myDataStruct myData;
}
这些类表示一个3级树,由一个基数,std::map<int,ptr*>
中的一些中间节点和每个节点的一些叶子组成,也是std::map<int,ptr*>
。在更新线程中动态生成和更新此树。
我有另一个线程从这些节点呈现数据,速度比更新慢得多,所以我更喜欢将更新操作与渲染分开。我不会在渲染线程的每个循环上渲染所有数据。
我最初的想法是注册我想通过调用一个函数来渲染叶子中的数据,该函数存储指向叶子中数据的指针:
void MyRenderClass::registerData(int* dataPointer) {
// store dataPointer in MyRenderClass
myStoredDataPointer = dataPointer;
}
然后在渲染线程循环期间,我使用该数据指针来渲染数据。
所以,问题是:这样安全吗?我可以通过取消注册相应析构函数中的数据来处理删除叶子或节点的情况。我真正想知道的是,指针是否会随着树的更新以及添加新的节点和叶子而保持不变? std::map
会重新排列或移动指针吗?被修改了吗?
在相关的说明中,我可以安全地存储指向叶子/节点中父节点/ base的指针,这样我就可以从leaf-&gt; base遍历树了吗?
我希望这是有道理的。起初我认为这似乎没问题,但我想在进一步走这条道路之前进行验证。这个例子有点做作,因为整个代码库太大而不能理解。
答案 0 :(得分:2)
这里的重要问题是:
std::map
重新排列或移动指针会被修改吗?
std::map
保证只要该对象保留在地图中,其对象的迭代器,引用和指针将保持有效。因此,只要不删除指向的对象,就可以安全地存储指针。
请注意,并非所有容器都提供此保证;例如,vector
将在超出其容量时移动其元素,并且必须分配新的内存块,以便将元素保持在连续的数组中。 (但即使这样,如果你存储指针,那么它们指向的对象也不会移动)。