C++ 删除树结构中的所有子项,同时通知父项
c++ deleting all children in a tree structure while informing the parent
考虑到这一点:
class A {
public:
A()
~A()
void add(A *child);
void remove(A *child);
void set_parent(A *parent);
private:
A *parent;
std::list<A*> children;
};
add, remove
和set_parent
显然会访问列表或父属性。
通过以下实现:
A::A() : parent(nullptr){};
A::~A() {
//Keep the hierarchy clean and inform parent that we are gone now
if(this->parent != nullptr) {
this->parent->remove(this);
}
//Also delete all children as they would be lost now ...
for(A *child : children) {
delete child;
}
}
void A::set_parent(A *parent)
{
if(this->parent != nullptr)
this->parent->remove(this);
this->parent = parent;
}
我实际上不想做任何更复杂的事情,但问题是,当删除列表的子级时,他们每个人都通知他们的父级他们现在已经消失了,操纵我们目前正在迭代的列表。一个人能做什么?
在删除子项之前"分离"父项怎么样?
A::~A() {
//Keep the hierarchy clean and inform parent that we are gone now
if(this->parent != nullptr) {
this->parent->remove(this);
}
//Also delete all children as they would be lost now ...
for(A *child : children) {
child->set_parent(nullptr); // Detach parent to avoid re-calling remove()
delete child;
}
}
我能想到的最简单和最直接的解决方案是简单地有一个布尔标志,当设置时会导致remove
什么都不做。在循环访问列表之前设置此标志。
然后我们有一个实际上可能更好的解决方案:智能指针。然后你根本不需要析构函数中的循环,当列表对象本身被破坏时,包含的指针将简单地"删除"自己。 std::shared_ptr
和std::enable_shared_from_this
是您可能想要为此学习的两个很好的参考。
然后是最好的解决方案,IMO:将元素的移除与析构函数分离。有一个显式函数,该函数从父元素中删除元素,并且在析构函数中没有 remove
调用。这与共享指针相结合,可能是处理它最安全的方法。不过,您可能需要进行一些重新设计(可能还需要一些重构)。
使用 std::list
很容易删除和迭代它,因为迭代器仅在删除相应元素时失效:
auto child = std::begin(children);
while(child != std::end(children))
{
auto next = child + 1;
delete *child;
child = next;
}
可以通过
不循环访问析构函数中的list
来避免此问题。相反,只要还有子项,就删除子项。
A::~A() {
//Keep the hierarchy clean and inform parent that we are gone now
if(this->parent != nullptr) {
this->parent->remove(this);
}
//Also delete all children as they would be lost now ...
while(children.empty() == false)
{
delete children.back();
}
}
你也可以做这样的事情:
for (auto it = children.begin(); it != children.end();)
{
(*it)->set_parent(nullptr)
delete *it;
it = children.erase(it);
}
相关文章:
- 将数组的地址分配给变量并删除
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- C/C++编译器通常会删除重复的库吗
- 从链接列表c++中删除一个项目
- C++如何通过用户输入删除列表元素
- 为什么在C++中使用私有复制构造函数与删除复制构造函数
- 是否需要删除包含对象的"pair"?
- 如何在自删除后将对象设置为nullptr
- 迭代时从向量和内存中删除对象
- 使用函数"remove"删除重复元素
- 如何从多映射中删除特定的重复项
- 运算符C++ "delete []"仅删除 2 个前值
- 删除指向指针的指针是运行时错误吗
- 通知 Windows 系统应用程序字体已被卸载/删除
- Windows Portable设备 - 创建 /复制 /删除新文件时通知
- C++ 删除树结构中的所有子项,同时通知父项
- 在列表框删除项目时收到通知
- 添加/删除/更新联系人时获得通知
- 在c++中,通知引用对象被删除
- 如何通知其他进程文件已标记为删除