我在使用C ++编写GUI时遇到了一个基本问题。
单击按钮时,应删除其父框架,并自行删除。 但是当删除按钮时,信号/插槽机制会明显导致分段错误。
当没有使用信号时,下面的代码模拟了类似的行为。 a是用孩子b创建的。要求删除b(类似于单击按钮)。
使用valgrind编译并运行时没有任何错误。
标题.h
class B;
class A {
private:
B* fB;
public:
A();
B* GetB() {return fB;}
void DeleteB();
};
class B {
private:
A* parent;
public:
B(A* a) {parent = a;}
void DeleteMyself();
};
实施
#include <iostream>
#include "test_delete.h"
A::A() {
std::cout << "Constructor A" << std::endl;
fB = new B( this );
}
void A::DeleteB() {
std::cout << "DeleteB " << std::endl;
if (fB != 0) {
std::cout << "delete fB " << std::endl;
delete fB;
fB = 0;
} else {
std::cout << "fB is already null" << std::endl;
}
}
void B::DeleteMyself() {
std::cout << "B::DeleteMyself" << std::endl;
std::cout << "this " << this << std::endl;
parent->DeleteB();
// this is printed after object is deleted
std::cout << "B::DeleteMyself after DeleteB" << std::endl;
// this has the same value
std::cout << "this " << this << std::endl;
}
的main.cpp
int main() {
// creates container A and child B
A * a = new A();
b = a->GetB();
// b will ask to its parent to be killed
b->DeleteMyself();
delete a;
}
所以我有两个问题:
我能想到两种解决方案:
重写GUI以具有用于删除对象的单独框架(如单独的列表,与要删除的框架无关)。但它看起来像现在一样直观。我有很多b,每个都有自己的删除按钮。
有人建议我使用一些计时器。设置一个标志,并调用一个函数来删除所有标记在1秒后的子节点。信号终止,对象被正确删除。我测试过,看起来很有效。但这种设计似乎更具诀窍。
我正在使用一个非常具体的GUI库ROOT(http://root.cern.ch/drupal/)。 也许这个限制是由于这个框架,但我不这么认为。
我试着说清楚, 在此先感谢您的建议, 迈克尔
答案 0 :(得分:4)
删除其中一个方法中的对象是可以的,前提是您在其余的方法代码中没有引用任何属性。
然而,GUI中的问题通常通过简单地“标记删除”小部件并在主事件循环中处理删除来解决。例如,参见Qt库的deleteLater
调用。