2016-01-14 2 views
5

Lassen Sie uns eine Klasse Test und eine Klasse AnotherClass haben. Beide stammen von QObject.Einen eigenen Destruktor definieren, obwohl die Klasse von QObject abgeleitet ist?

Test.h:

class Test : public QObject 
{ 
Q_OBJECT 

public: 
    Test(QObject* parent); 
    ~Test(); 

private: 
    AnotherClass* other; 
}; 

class AnotherClass : public QObject 
{ 
Q_OBJECT 

public: 
    AnotherClass(QObject* parent); 
    ~AnotherClass(); 
}; 

Test.cpp:

Test::Test(QObject* parent) : QObject(parent) 
{ 
    other = new AnotherClass(this); 
} 

Test::~Test() 
{ 
    delete other; 
} 

other automatisch zerstört werden, wenn die Test -instance zerstört wird, weil Test ist die Mutter von other, nicht wahr?

  • Jetzt soll ich von mir selbst löschen other in ~Test() oder es das Programm in einem undefinierten Bühne nicht verlassen, weil sie zweimal das gleiche Objekt zu löschen versucht?
  • Was ist der richtige Ansatz hier?
+1

Ihre Destruktoren sollten virtuell sein. – KoVadim

+4

@KoVadim - Da QObject über einen virtuellen Destruktor verfügt, sind seine Destruktoren implizit bereits virtuell. – Roddy

Antwort

10

QObjects organisieren sich in Objektbäumen. Wenn Sie ein QObject mit einem anderen Objekt als übergeordnetes Objekt erstellen, wird das Objekt automatisch zu der children() Liste des übergeordneten Elements hinzugefügt. Der Elternteil übernimmt das Eigentum an dem Objekt; d.h., es löscht automatisch seine Kinder in seinem Destruktor. Weitere Informationen finden Sie unter Object Trees & Ownership.

Weil Sie diese Zeiger von -Test Objekt Andere Konstruktor übergeben, bedeutet es, dass Sie -Test Objekt als Eltern von Andere verwenden. So löschen Test Objekt löscht auch seine Kind und Sie müssen nicht explizit löschenandere.

In diesem Fall jedoch explizite Löschung im Destruktor verursacht keine doppelte Löschung, weil es die Aufhebung der Registrierung von der Children() - Liste der Eltern verursacht.

4

Abgesehen von der Tatsache, dass Sie den destructor virtual machen müssen, die Qt-Dokumentation sagt:

Wenn QObject s auf dem Heap erstellt werden (dh mit new erstellt), ein Baum kann aus ihnen in beliebiger Reihenfolge konstruiert werden, und später können die Objekte in der Baum in beliebiger Reihenfolge zerstört werden. Wenn QObject in der Struktur gelöscht wird, wenn das Objekt einen übergeordneten hat, entfernt der Destruktor automatisch das Objekt von seinem übergeordneten. Wenn das Objekt untergeordnete Objekte hat, löscht der Destruktor automatisch jedes untergeordnete Objekt. No QObject wird zweimal gelöscht, unabhängig von der Reihenfolge der Zerstörung.

So können Sie delete die other Klasse explizit, aber Sie müssen nicht. Beide Ansätze sollten ohne Doppel delete s funktionieren.

Übrigens könnten Sie auch die AnotherClass ein einfaches Mitglied von Test anstelle eines Zeigers machen.

+1

Sie sollten es nicht zu einem einfachen Member machen, da QObjects nicht kopierbar/.assignable sind. – Roddy

+0

Sorry, virtueller Destruktor. Dies wurde bereits erwähnt, siehe https://stackoverflow.com/questions/461203/when-to-use-virtual-destructors – hfhc2

Verwandte Themen