题
我对在Qt4中使用析构函数感到非常困惑,并希望,你们可以帮助我 当我有这样的方法时(“Des”是一个类):
void Widget::create() {
Des *test = new Des;
test->show();
}
如何确保此小部件在关闭后将被删除?
在课堂上“Des”我有这个:
Des::Des()
{
QPushButton *push = new QPushButton("neu");
QHBoxLayout *layout = new QHBoxLayout;
layout->addWidget(push);
setLayout(layout);
}
我在哪里以及如何删除* push和* layout?什么应该在析构函数Des :: ~Des()?
解决方案
使用 deleteLater()
或parent的另一个选择是使用小部件的delete-on-close功能。在这种情况下,Qt将在完成显示时删除它。
Des *test = new Des;
test->setAttribute( Qt::WA_DeleteOnClose );
test->show();
我喜欢将它与Qt保留的对象树一起使用,以便我为窗口设置delete-on-close,并且窗口中的所有窗口小部件都指定了正确的父窗口,因此它们也都会被删除。 / p>
其他提示
Qt使用他们所谓的对象树,它与它有点不同典型的RAII方法。
QObject
类构造函数获取指向父 QObject
的指针。当该父 QObject
被破坏时,其子代也将被销毁。这是Qt类中非常普遍的模式,您会注意到很多构造函数都接受 * parent
参数。
如果您查看一些Qt 示例程序,您将会发现他们实际上在堆上构造了大多数Qt对象,并利用这个对象树来处理破坏。我个人认为这个策略也很有用,因为GUI对象可以有特殊的生命周期。
如果你没有使用 QObject
或 QObject
的子类(例如 QWidget
),Qt不提供标准C ++之外的额外保证。
在您的特定示例中,无法保证删除任何内容。
对于 Des
,你需要这样的东西(假设 Des
是 QWidget
的子类):
class Des : public QWidget
{
Q_OBJECT
public:
Des(QWidget* parent)
: QWidget(parent)
{
QPushButton* push = new QPushButton("neu");
QHBoxLayout* layout = new QHBoxLayout(this);
layout->addWidget(push); // this re-parents push so layout
// is the parent of push
setLayout(layout);
}
~Des()
{
// empty, since when Des is destroyed, all its children (in Qt terms)
// will be destroyed as well
}
}
你会像这样使用class Des
:
int someFunction()
{
// on the heap
Des* test = new Des(parent); // where parent is a QWidget*
test->show();
...
// test will be destroyed when its parent is destroyed
// or on the stack
Des foo(0);
foo.show();
...
// foo will fall out of scope and get deleted
}
Richardwb的答案很好 - 但另一种方法是使用deleteLater插槽,如下所示:
Des *test = new Des;
test->show();
connect(test, SIGNAL(closed()), test, SLOT(deleteLater()));
显然,闭合()信号可以用你想要的任何信号代替。
本教程建议您不需要显式删除已添加到父窗口小部件的窗口小部件。它还说删除它们也没有什么坏处。
(我没有测试过这个,但我想只要你在删除父窗口小部件之前明确删除它们,这应该没问题。)
在大多数情况下,您应该在堆栈上创建小部件:
QPushButton push("neu");
这样,当它们超出范围时会被删除。如果你真的想在堆上创建它们,那么你不负责在不再需要时调用它们。