背景故事:
我检查了一些代码,并且我已经创建了一个本地QMessageBox
来显示错误,并将其分配给堆:
if (getAutopilotList.error() == 0) {
QMessageBox* error = new QMessageBox(0);
error->setDetailedText(getAutopilotList.errorString());
error->setText("something");
error->setWindowTitle(tr("Error!"));
error->show();
return;
}
开发商说:
此指针将泄漏,您没有设置父项,您永远不会删除 它。在这里你也不需要指针。至于父母没有 使用0,但Core :: ICore :: mainWindow()。
我很困惑,因为我想:
delete error;
。我尝试将QMessageBox放在堆栈上,但它没有显示。
delete
QMessageBox指针?答案 0 :(得分:4)
我尝试将QMessageBox放在堆栈上,但它没有显示。
因为当线程超出范围时它会立即被销毁。您必须使用QMessageBox::exec()
以块模式运行它。
答案 1 :(得分:4)
原则上,您可以在堆栈上创建QWidget对象。在这里,它不起作用,因为对error->show()
的调用没有立即显示消息框,它只是在返回主偶数循环时调度显示,此时对象将被销毁。出于这个原因,delete
QMessageBox
也不会起作用。设置父对象会在父对象被销毁时将对象销毁的责任归于父对象,这是一个好主意。
但是,如果我了解您要执行的操作,则需要等待用户在return
之前单击“确定”按钮。如果是这种情况,您最好使用静态QMessageBox
功能,例如QMessageBox::warning。
如果您想要一个持久性消息框,那么您的代码就可以了,但您应该添加以下调用:
error->setAttribute(Qt::WA_DeleteOnClose);
当相应的窗口关闭时,这将触发删除。
答案 2 :(得分:3)
看看任何(很多)Qt示例,你会发现模式:
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MainWindow window; //inherits from QWidget, created on stack
window.show();
return app.exec();
}
1)关于“堆栈上的QWidget”这个问题 - 它应该是证明,它是有效的和官方的。但是这次和QDialog :: exec再次是堆栈上QWidgets的唯一用例。
2)它不会伤害。如果您的编码规则要求为每个新调用删除 - 请执行此操作。否则,正确设置Qt :: WA_DeleteOnClose,并在关闭时删除它。
3)关于父0:当丢失对具有父项的指针的引用时,您是安全的。如果删除父项,则会自动删除所有子项(也可能已被遗忘)。因此对于长期运行的应用程序,“内存泄漏”只是暂时的。 使用parent = 0,它不会在c ++意义上泄漏,这使得内存检查器无法检测到此类泄漏。仍然可以使用一些QObject树遍历函数访问指针。