我在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;
我已经读过可以删除它。我很难理解这一点。
答案 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,除非你正在编写相对较低级别的代码(比如你自己的内存分配器)。