【发布时间】:2017-08-23 14:13:05
【问题描述】:
我在 GUI 中有一个窗口系统,但我不确定销毁顺序。每个 Window 都有一个包含其子级的向量,每个 Window 也有一个指向其父级的指针:
auto root = new Window;
root->addChild(new Window);
root->addChild(new Window);
auto child = root->addChild(new Window); // Return value is the newly created Window
child->addChild(new Window);
child->addChild(new Window);
auto grandchild = child->addChild(new Window);
grandchild->addChild(new Window);
grandchild->addChild(new Window);
grandchild->addChild(new Window);
// 我想删除子指针,首先我需要从它的父子向量中删除它的指针。
child->parent->children.erase(child->parent->children.begin() + child->positionInParentsVector - 1);
child->destroy();
void Window::destroy()
{
if (children.size() == 0) delete this;
else for (auto i : children) i->destroy();
}
或者使用智能指针向量,这样做是否足够:
// Remove reference of child from parent's children vector, then
delete child;
我已经读到删除它是可以的。我很难理解这一点。
【问题讨论】:
-
智能指针可能是最好的,所以它会自动清理。但是,如果您的层次结构 非常 深,您可能会在析构函数中遇到堆栈溢出。在这种情况下,您将需要像您展示的那样“手动”发布所有内容。
-
另外,因为destroy函数是递归的,我只需要在最高级别删除父级的引用一次,这意味着我需要创建一个函数来删除引用,另一个函数来删除引用做递归删除,对吗?那可能是三个函数,一个是 removeReferenceAndDestroy,一个是 removeReference,然后执行递归 destroy()。没有更优雅的方式了吗?
-
如果堆栈溢出 是 一个现实问题(它也会发生在常规层次递归遍历中)那么它实际上 不是 像你展示的那样,你需要不用递归而是用循环来做。
-
基本上智能指针 dtor 会自动执行您所做的操作。
-
如果你有一个
addChild,你不应该有一个相应的removeChild让父母进行清理吗?对我来说,child->destroy()似乎是从delete child调用时析构函数应该做的事情(但没有delete this)。
标签: c++ vector parent hierarchy