Wann deleteLater
Vorausgesetzt, ich habe Folgendes snippet, ist es sicher zu nennen, deleteLater in qto der Destruktor für andere QT-Objekte, die es möglicherweise verwalten?
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MyQTObject qto;
qto.show();
return a.exec();
}
Da habe ich analysiert ähnlicher code wie dieser mit einem Leck-Detektor und alle Objekte, für die deleteLater genannt wurde, waren nicht freigegeben, richtig, es sei denn, ich ersetzte Sie den Anruf mit einer normalen löschen.
Wenn ich das richtig verstanden hab, deleteLater registriert nur ein Ereignis löschen in der QT message queue. Kann dies das problem sein, dass qto der Destruktor aufgerufen wird am Ende von main-Gültigkeitsbereich in der Erwägung, dass die QT-message-Schleife bereits endet mit der Rückgabe aus.exec? Also das löschen-Ereignis nie verarbeitet werden, in der Tat nicht einmal geschoben, in eine message-queue, da es keines gibt?
- Sie nicht brauchen, deletelater auf
qto
. es ist auf den stack. Btw analyzer can-report von false-positives. - die Frage, die fragt, ob es sicher ist zu nennen, deleteLater...für ANDERE QT-Objekt, es könnte zu verwalten, nicht für qto selbst.
- Dies ist ganz einfach zu testen. Setzen Sie einfach einige debug-Meldungen in den Destruktor und sehen, wenn Sie auftauchen. Sie werden feststellen, dass Sie nicht. Gibt es einen Grund, diese Objekte sind keine Kinder von
qto
?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wie ich es verstehe, deleteLater wird am häufigsten verwendet, wenn Sie eine zu löschende Objekt aus der Anruf zu einem slot. Wenn delete verwendet wird, in diesem Fall, und das Objekt wird referenziert, wenn der Rückkehr aus dem slot, einen Verweis auf uninitialised Speicher Auftritt.
Daher, deleteLater Anforderungen dieses Objekt gelöscht werden, indem eine Nachricht auf dem Ereignis-Schleife, die verarbeitet wird, an einem gewissen Punkt, nach der Rückkehr aus dem Schlitz und es ist sicher gelöscht werden.
Ich erwarte, dass mit deleteLater im Destruktor heißt, es gibt eine wahrscheinliche Möglichkeit, dass das Objekt den Gültigkeitsbereich verlässt, ruft deleteLater auf die verwalteten Objekte, aber beendet, bevor die Ereignis-Schleife eine chance hat, löschen Sie die Objekte, wie den Ausstieg aus QApplication::exec() beendet die event-Schleife.
Dieser post ist eher im Alter, aber hinzufügen möchte ich, dass die Antwort, die ich gern haben würde, zu stoßen, wenn ich mich auch gefragt.
deleteLater()
kann sehr nützlich sein in Kombination mit asynchronen Operationen. Besonders glänzt, denke ich, mit den neueren Möglichkeit der Verbindung Signale der lambda-Funktionen.Angenommen, Sie haben einige
longComputation()
, die Sie möchten ausführen, asynchron (nicht im Sinne von Multi-Threading, im Sinne der scheduling-Ausführung in der event-Schleife). Sie können dies so tun:wo
deleteLater()
kümmert sich um die sicher Entsorgung vonQTimer
einmal seine Pflicht hat, durchgeführt wurden und vermeiden Sie den memory-leak, die man sonst hätte.Dem gleichen Muster kann verwendet werden, in multithreading mit
QFutureWatcher
.QTimer::singleShot(0, this, longComputation);
deleteLater()
ist ein ziemlich low-level-feature und Sie können oft höhere level-Konstrukte, die die Arbeit für Sie erledigen.singleShot
Sortieren von Adressen, die Fall, da es statisch ist und Sie können eine Wartezeit im call. Ich war nur neugierig. Deine Umsetzung sieht viel wie der Qt-Dokumentation die Erklärung von dem, was singleShot hat. Ich benutzeQTimer::singleShot
Recht ausführlich gegen die Seriell und Buchse angeschlossenen hardware-Geräte. Man muss oft warten, bis Sie zu "beruhigen" vor dem senden mit einem anderen Befehl. Danke.Die Frage ist alt, aber das überlasse ich für die zukünftige generation)
Die Antwort, die markiert war, als eine Antwort ist richtig, aber seltsam formuliert.
Deine Frage enthält eine richtige Antwort:
Dies ist genau das, was passiert ist. Alles
deleteLater()
tut, ist einfach nur posten einer Löschung eine Veranstaltung in der outter-event-Schleife. Bei der Veranstaltung bekommt proccessed - Objekt gelöscht wird. Aber wenn es nicht outter-event-Schleife und keine Ereignis-Schleife begegnet, die später in der Ausführung flow - Ereignis wird nie gepostet, somit Objekt ist, niemals gelöscht.Wenn Sie anrufen
deleteLater()
in der Objekt-Destruktor und setzen Sie ein Objekt auf dem stack -deleteLater()
wird aufgerufen, wenn das Objekt außerhalb des Gültigkeitsbereichs. In deinem Beispiel "going out of scope" passiert, wenn die schließende Klammer vonmain()
Funktion aufgetreten ist. Jedoch, durch die Zeit,a.exec()
(die stellt die Haupt-Ereignisschleife des Qt-App) hat bereits wieder --> keine Ereignis-Schleife mehr -->deleteLater()
genannt wurde, aber es ist nirgendwo zu posten ein Ereignis löschen --> Objekte wurden angeblich "deletedLater" nie gelöscht...In Bezug auf den Teil "bei, mit deleteLater()":
Kuba Ober antwortete:
Nicht hören, es ist absolut falsch, wie die ganze Antwort. Was man tun sollte und was sollte nicht Sie besser entscheiden, nach dem Lesen dieser Artikel. Obwohl, es ist vor allem über die Qt-threads, der Artikel erzählt auch über ascynchronous Programmierung (und, wie Emerald Weapon erwähnt, ist es genau das, was deleteLater() erstellt wurde).
Auch, smart Pointer und QObject Eltern Eigentum haben nichts zu tun mit der Planung für die Löschung mit
deleteLater()
. Diese beiden Techniken sind eigentlich mit einem einfachendelete
Bedienung unter der Haube. Und wie der Artikel zeigt, und wie Emerald Weapon's Antwort gezeigt:delete
löst die Probleme nichtdeleteLater()
tut. Also, wenn Sie brauchen, um zu löschen Objekt, das Sie verwendendelete
, wenn Sie planen, es für das löschen verwenden SiedeleteLater()
.BTW, wenn Sie wollen smart-pointer mit
deleteLater()
Sie können die deleter:Endlich, Es ist ein NICHT einen Fehler zu verwenden
deleteLater()
im Destruktor vonQObject
, für nicht-untergeordnete Objekte.Sind Sie richtig, dass die
deleteLater()
Befehl wird nur ausgeführt, durch eine event-Schleife.Aus der Qt-Dokumentation für
QObject
:Wenn Sie möchten, dass alle Kind
QObjects
werden gelöscht, wennqto
gelöscht wird, stellen Sie sicher, Sie sind erstellt mitqto
als die Eltern.Allgemein gesprochen, gibt es eine schmale Reihe von Umständen, wo deleteLater verwendet werden soll. Wahrscheinlich haben Sie einfach nicht benutzen sollte es.
Es ist ein Fehler, um es in den Destruktor von QObject, für nicht-untergeordnete Objekte. Wie hast du Sie gefunden QObjects kann gut sein, zerstört, ohne eine Ereignis-Schleife vorhanden. Es gibt keine
deleteLater
ruft Sie im Objekt-Destruktoren derqtbase
Qt-Modul, zum Beispiel.Muss man hier vorsichtig sein: zum Beispiel
~QTcpServer()
ruftclose()
aufrufend->socketEngine->deleteLater()
, aber die socket engine ist bereits ein Kind von dem server und wird gelöscht werden, indem~QObject()
sowieso.Für alle ich wissen, ist
MyQTObject
sollten Sie eine der folgenden Optionen:QScopedPointer
oderstd::unique_ptr
,