删除父/子窗口层次结构的最佳方法

时间:2017-08-23 14:13:06

标签: c++ vector parent hierarchy

我在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;

我已经读过可以删除它。我很难理解这一点。

1 个答案:

答案 0 :(得分:1)

我觉得你有点困惑自己。以下自包含示例没有内存泄漏:

#include <utility>
#include <vector>
#include <memory>

using std::vector;
using std::unique_ptr;

struct Window {
    Window() = default;
    vector<unique_ptr<Window>> children;
    Window* parent = nullptr;
    ~Window();

    Window* addChild(std::unique_ptr<Window> c) {
        c->parent = this;
        children.push_back(std::move(c));
        return children.back().get();
    }
};

Window::~Window() = default;

int main() {
    auto root = std::make_unique<Window>();
    root->addChild(std::make_unique<Window>());
    auto child = root->addChild(std::make_unique<Window>());
    child->addChild(std::make_unique<Window>());
};

类不能包含自身,但它可以包含unique_ptr本身(或其容器)。在此方案中,所有递归破坏都会正确且自动地发生。当然,你可以用各种方式来装扮它,但这是基本的想法。

这里有一些关于良好对象和类设计和封装的其他问题,但这是另一个问题。注意:在绝大多数情况下,您不应该有一个名为destroy的方法,但这应该在析构函数中发生。

基本上不需要在C ++ 11或更高版本中编写new或delete,除非你正在编写相对较低级别的代码(比如你自己的内存分配器)。

实例:http://coliru.stacked-crooked.com/a/adef8cc40de4916a