C ++在迭代

时间:2017-02-12 18:41:34

标签: c++ recursion tree tree-traversal

我有一个基于树的场景。 迭代更新所有对象的方式如下:

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。

0 个答案:

没有答案