我有一个基于树的场景。 迭代更新所有对象的方式如下:
void IUpdatableTreeItem::updateTree(float pDt)
{
updateSelf(pDt); ///< pure virtual
for (int i = 0; i < (int)d_children.size(); ++i)
{
if (auto* pUpdatableChild =
dynamic_cast<IUpdatableTreeItem*>(d_children[i]))
{
pUpdatableChild->updateTree(pDt);
}
}
}
我通过&#34; updateSelf&#34;更新对象然后去找它的孩子递归更新所有这些。 &#34; updateSelf&#34;是一个纯虚函数,可以做任何想做的事情,包括自我删除,删除任何孩子甚至自己的父母。 删除是微不足道的:从父母列表中删除自己(如果有的话),递归删除所有孩子并且&#34;删除这个&#34;最后。
如果我尝试删除&#34; updateSelf&#34;中的当前对象。 function - 我在访问d_children时遇到了一个合法的例外。
有一个选项(我认为相当差)将自我标记为&#34;删除&#34;直接&#34;删除此&#34;并在每一步检查它。我们不仅应该通过一些&#34; deleteSelf&#34;来标记要删除的对象,还要标记所有它的孩子。功能
void IUpdatableTreeItem::updateTree(float pDt)
{
if (deleted)
return;
updateSelf(pDt); /// This contains a call to deleteSelf();
for (int i = 0; i < (int)d_children.size(); ++i)
{
if (auto* pUpdatableChild =
dynamic_cast<IUpdatableTreeItem*>(d_children[i]))
{
if (deleted)
return;
pUpdatableChild->updateTree(pDt);
if (pUpdatableChild.deleted)
removeChild(pUpdatableChild);
}
}
}
然后删除所有&#34;已删除&#34;父母的对象。
第二个选项是删除第二遍中的所有标记对象(似乎也不是最佳的)。这两个选项对我来说都很难看。
有没有办法避免第二次通过并避免检查每一行?
UPD:
删除项目也意味着删除所有孩子。 Dtor看起来像这样:
ITreeItem::~ITreeItem()
{
for (auto child : d_children)
delete child;
}
这意味着在删除父母后,我无法引用当前的obj的d_children。