Frage
Ich bin sehr verwirrt über Destruktoren in Qt4 und Hoffnung mit, euch kann mir helfen.
Wenn ich eine Methode wie diese habe (mit „Die“ ist eine Klasse):
void Widget::create() {
Des *test = new Des;
test->show();
}
Wie kann ich sicherstellen, dass dieses Widget gelöscht werden soll, nachdem es geschlossen wurde?
Und in der Klasse "Die" Ich habe diese:
Des::Des()
{
QPushButton *push = new QPushButton("neu");
QHBoxLayout *layout = new QHBoxLayout;
layout->addWidget(push);
setLayout(layout);
}
, wo und wie muss ich * push und * Layout löschen? was in dem destructor Des :: ~ Des () enthalten sein sollte?
Lösung
Eine weitere Möglichkeit zur Verwendung von deleteLater()
oder Eltern, ist die Lösch-on-close-Funktionalität für Widgets zu verwenden. In diesem Fall wird Qt das Widget löschen, wenn es angezeigt wird getan.
Des *test = new Des;
test->setAttribute( Qt::WA_DeleteOnClose );
test->show();
Ich mag es verwenden, um mit dem Objektbaum, die Qt hält, so dass ich für das Fenster lösche beim Schließen eingestellt, und alle Widgets im Fenster haben ein richtig Eltern angegeben, so dass sie alle als gut gelöscht.
Andere Tipps
Qt verwendet, was sie rufen Sie Objekt Bäume und es ist ein bisschen anders der typische RAII Ansatz.
Die QObject
Klasse Konstruktor einen Zeiger auf einen Elternteil QObject
nimmt . Wenn das Mutter QObject
zerstört wird, werden seine Kinder als auch zerstört werden. Das ist ein ziemlich weit verbreitet Muster über Qt-Klassen und Sie werden eine Menge von Konstrukteuren einen *parent
Parameter akzeptieren bemerken.
Wenn Sie auf einige der Beispielprogramme werde feststellen, dass sie tatsächlich die meisten Qt Objekte auf dem Heap konstruieren und Vorteil dieses Objektbaum nehmen Zerstörung zu handhaben. Ich persönlich fand diese Strategie nützlich als auch als GUI-Objekte eigentümliche Lebenszeiten haben können.
Qt stellt keine zusätzliche Garantien über Standard-C ++, wenn Sie nicht QObject
oder eine Unterklasse von QObject
(wie QWidget
) verwendet wird.
In Ihrem speziellen Beispiel gibt es keine Garantie, dass alles gelöscht wird.
Sie so etwas für Des
wollen werden (unter der Annahme Des
ist eine Unterklasse von 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
}
}
Und du würdest Klasse Des
verwenden wie folgt:
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 Antwort ist gut - aber der andere Ansatz ist, die deleteLater Slot zu verwenden, etwa so:
Des *test = new Des;
test->show();
connect(test, SIGNAL(closed()), test, SLOT(deleteLater()));
Offensichtlich ist das geschlossen (Signal) mit ausgetauscht werden kann, was auch immer Signal, das Sie wollen.
Dieses Tutorial deutet darauf hin, Sie müssen nicht explizit Widgets löschen, die Eltern-Widgets hinzugefügt wurden. Er sagt auch, es nicht zu tun, tut nicht weh, sie entweder löschen.
(ich nicht getestet habe, aber ich denke, solange man sie explizit gelöscht werden, bevor die Mutter Widget gelöscht wird, dies in Ordnung sein sollte.)
In den meisten Fällen sollten Sie Widgets auf dem Stapel erstellen:
QPushButton push("neu");
Auf diese Weise, sie gelöscht werden, wenn sie sich außerhalb des Geltungsbereichs werden. Wenn Sie wirklich auf dem Heap erstellt werden sollen, dann ist es in Ihrer Verantwortung auf sie zu nennen löschen, wenn sie nicht mehr benötigt werden.