这是令人反感的代码:
class FullPage : public QWidget
{
Q_OBJECT
public:
explicit FullPage(const AppData* appdata, QWidget* parent = 0);
virtual void addIconWorking(IconWorking* temp);
virtual void removeIconWorking(IconWorking* temp);
...
}
class IconWorking : public QLabel
{
Q_OBJECT
public:
explicit IconWorking(FullPage* parent = 0);
virtual ~IconWorking();
...
}
IconWorking::IconWorking(FullPage* parent) : QLabel(parent)
{
...
parentPage = parent;
parentPage->addIconWorking(this);
...
}
IconWorking::~IconWorking()
{
parentPage->removeIconWorking(this); //segfault
QMessageBox::information(0, "TODO", "Reminder Message");
}
我想念什么?
更新:
我在注释中添加了一些测试代码,以查看parentPage是否曾经更改。没有。我正在使用在构造函数中分配并在析构函数中检查的新创建的变量。
segfault消息未指定地址。如果这样的话会很好。直接检查指针会得到一个非零值,无论是原始测试还是添加的测试,因此它们都不为null。
我还发现,当我添加一些功能时,会在一个完全不相关的位置中得到一个新的段错误,它引用了在整个程序的参数中传递的同一FullPage实例。
最佳答案
假设~IconWorking()
的parentPage被销毁时被调用,如父子关系所示:
当parentPage对象被销毁时,事情按以下顺序发生:
在~FullPage()
实例上调用
parentPage
。之后,parentPage不再是有效的FullPage对象! ~Widget()
被调用,剩下一个QObject。 ~QObject()
会被调用,这会删除您的IconWorking对象(由于父子关系)~IconWorking()
被执行,它在parentPage上调用FullPage::removeIconWorking(),我假设它访问的是在步骤1中已销毁的FullPage特定成员。(parentPage指向的对象此时仅是一个有效的QObject,没有其他对象!)为了使此方法有效,〜FullPage()必须手动删除IconWorking对象,而不是依赖QObject父子关系。