Frage

Hier, meine Signaldeklaration:

signals:
    void mySignal(MyClass *);

Und wie ich verwende es:

MyClass *myObject=new myClass();
emit mySignal(myObject);

Hier kommt mein Problem: Wer zum Löschen von myObject verantwortlich ist:

  1. Sender-Code, was, wenn es vor myObject löscht verwendet wird? Dangling Pointer

  2. Die Schlitz-Signal verbunden, was ist, wenn es keinen Schlitz oder mehr als ein Schlitz, der mit dem Signal verbunden ist? Speicherverlust oder baumelnde Zeiger

Wie schafft Qt diese Situation in seinem Build-in-Signale? Gibt es interne Referenzzählung verwenden?

Was sind Ihre besten Praktiken?

War es hilfreich?

Lösung

Sie können ein Signal mit so vielen Slots verbinden, wie Sie möchten, so sollten Sie sicherstellen, dass keine dieser Schlitze sind in der Lage, etwas zu tun würden Sie nicht wollen, dass sie mit Ihrem Objekt zu tun:

Siehe auch diese Frage für einige Gedanken über Zeiger in Signale übergeben.

Andere Tipps

Für Ihre erste Frage, die Verwendung QPointer

Für Ihre zweite Frage,

Wenn ich klar verstanden, auch wenn Sie myObject senden, Sie immer noch die Referenz hat myObject in der Klasse, in der Sie das Signal emittiert. Dann, wie es wird ein Speicherleck oder ein baumelnden Zeiger sein? Sie können immer noch Zugriff die myObject aus der emittierten Klasse, nicht?

Hope ist klar ..

Edit:

Von Ihre Kommentare Ich glaube, Sie sind die Freigabe / die Objekte in die Schlitze zu löschen. Nun gehe ich davon aus, Ihr Problem ist, was passiert, wenn der (Speicher Freigabe) Schlitz einmal aufgerufen wird, zweimal oder gar nicht genannt.

Sie können QPointer dafür. Von der Qt-Dokumentation

Bewacht Zeiger (QPointer) sind nützlich, wenn Sie einen Zeiger auf eine QObject speichern müssen, die von jemand anderem gehört, und deshalb zerstört werden könnte, während Sie noch einen Verweis auf sie halten. Sie können sicher den Zeiger auf Gültigkeit prüfen.

Ein Beispiel aus der Qt-Dokumentation selbst,

     QPointer<QLabel> label = new QLabel;
     label->setText("&Status:");
     ...
     if (label)
         label->show();

Die Erklärung geht weiter so ..

Wenn die QLabel in der Zwischenzeit gelöscht wird, wird das Etikett Größe 0 halten, anstatt eine ungültige Adresse, und die letzte Zeile wird nie ausgeführt werden. Hier QLabel wird Ihr MyClass und Label ist Ihr myObject. Und bevor es überprüft Ungültigkeit verwenden.

1): Der Absender sollte darauf achten. Wenn das Signal synchron Senden (statt der Warteschlange), ist das Objekt noch am Leben, wenn ein Empfänger die ihn empfängt. Wenn der Empfänger Bedürfnisse zu speichern, nur ein QPointer helfen würde, aber dann muss MyClass von QObject abzuleiten, die aus dem Kontext falsch aussieht. Wie auch immer, das ist eine allgemeine Lebensdauer Problem, nicht sehr Signal / Slot-spezifisch ist.

Alternativen: Verwenden Sie einen Wert Klasse und über konstante Referenz senden. Wenn MyClass Subklassen haben kann, passieren eine const QSharedPointer &

Über deleteLater: deleteLater () hilft hier nicht. Es wäre Verbindungen nicht sichere Warteschlange machen, und für direkte Verbindungen macht es keinen Unterschied. Die eine Verwendung, wo deleteLater () ins Spiel kommt, wenn der Empfänger den Sender löschen muss. Dann sollte man immer verwenden deleteLater (), so kann der Absender vervollständigen, was er tat, was sonst abstürzen würde.

In einem Wort (in Ordnung, Funktionsname) - deleteLater () :) Alle QObjects es haben. Es wird das Objekt zum Löschen markieren, und dies wird dann auf der nächsten Ereignisschleife Update passieren.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top