C ++是否符合以及如何从信号中删除小部件

时间:2014-09-29 14:47:42

标签: c++ frame

我在使用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;
}

所以我有两个问题:

  • 这段代码真的有效吗?一旦对象被删除,在B的功能中似乎很奇怪。
  • 在GUI中实现删除按钮的最佳方法是什么?

我能想到两种解决方案:

  • 重写GUI以具有用于删除对象的单独框架(如单独的列表,与要删除的框架无关)。但它看起来像现在一样直观。我有很多b,每个都有自己的删除按钮。

  • 有人建议我使用一些计时器。设置一个标志,并调用一个函数来删除所有标记在1秒后的子节点。信号终止,对象被正确删除。我测试过,看起来很有效。但这种设计似乎更具诀窍。

我正在使用一个非常具体的GUI库ROOT(http://root.cern.ch/drupal/)。 也许这个限制是由于这个框架,但我不这么认为。

我试着说清楚, 在此先感谢您的建议, 迈克尔

1 个答案:

答案 0 :(得分:4)

删除其中一个方法中的对象是可以的,前提是您在其余的方法代码中没有引用任何属性。

然而,GUI中的问题通常通过简单地“标记删除”小部件并在主事件循环中处理删除来解决。例如,参见Qt库的deleteLater调用。