2016-07-12 14 views
2

Ich entwickelte eine Qt-Anwendung, die ein Authentifizierungs-Widget und ein Hauptfenster hat. Nach der Authentifizierung gelingt ich die Mainwindow mit diesem Code öffneQt doppelt frei oder Korruption

this->~Authentification(); 
MainWindow *w = new MainWindow(); 

aber nachdem ich das Hauptfenster schließen erhalte ich einen doppelten frei oder Korruption Fehler. die Debug sagte, dass die Quelle dieses Fehlers

delete ui; 

aus der Klasse Authentification

+0

Does Authentification inehrit von QObject durch Zufall? Destruktoren aus einer Klasse zu starten, während dies technisch möglich ist, ist schwierig zu debuggen, wenn etwas schief geht (Sie müssen sicherstellen, dass es später nicht berührt wird). Wenn Authentifizierung QObject ist, dann empfehle ich die Verwendung this -> deleteLater(); Außerdem übergibst du MainWindow keinen Elternteil und da du in der jetzt zerstörten Klasse neu aufrufst, verlierst du Speicher, da du diesen Zeiger möglicherweise nicht erhalten kannst, um ihn zu löschen. Wenn Sie es nach diesem Anruf anzeigen und dann löschen ... arbeiten Sie immer noch in der zerstörten Klasse. Sieht nach sehr schlechter Designentscheidung aus. – Resurrection

+0

Niemals Destruktoren explizit aufrufen. Außer "Platzierung neu" ist das ein seltener Fall. – ilotXXI

+0

ja Authentifizierung ist ein QWidget und inehrit von QObject. Das Problem ist, wenn ich dies nannte -> ~ Authentifizierung(). Die Authentifizierungsklasse ist nicht vollständig geschlossen und wenn ich das Hauptfenster schließe, ruft sie auch ~ Authentification() ein anderes Mal an. – Dababi

Antwort

1

Sie explizit den destructor auf this Aufruf ist. Es gibt sehr wenige Male, die Sie tun müssen, und sie sollten immer abstrahiert werden. Solche Aufrufe gehören nur in Ressourcenmanagementklassen niedriger Ebene. Wenn Sie daran denken, dies in einer Unterklasse von QObject oder QWidget zu tun, sollten Sie wahrscheinlich nicht sein! Wenn Sie nur ein Fenster schließen möchten, verwenden Sie QWidget::close(). Vielleicht möchten Sie aber auch die Widget-Instanz zerstören, um die von ihr verwendeten Ressourcen freizugeben. Dann lesen Sie weiter.

Nehmen wir an, dass Authentication ein richtiger Dialog ist die accepted() und rejected() ggf. Signale aussendet, wenn die Authentifizierung oder nicht erfolgreich ist, jeweils:

class Authentication : public QDialog { 
    ... 
}; 

Einige Möglichkeiten, aus einem solchen Vorgehen ein Dialog sein könnte:

  1. Definieren Sie den Dialog als lokale Variable für einen Bereich, führen Sie eine Ereignisschleife aus, solange das Dialogfeld aktiv ist, und belassen Sie dann den Bereich:

    int main(int argc, char ** argv) { 
        QApplication app{argc, argv}; 
        { 
        Authentication auth; 
        auto result = auth.exec(); 
        if (result == QDialog::Rejected) return 1; 
        } // here auth has been destructed 
        MainWindow window; 
        window.show(); 
        return app.exec(); 
    } 
    
  2. Weisen Sie den Dialog dynamisch zu und lassen Sie ihn beim Schließen automatisch löschen.

    int main(int argc, char ** argv) { 
        QApplication app{argc, argv}; 
        auto auth = new Authentication; 
        auth->setAttribute(Qt::WA_DeleteOnClose); 
        QObject::connect(auth, &QDialog::accepted, []{ 
        auto win = new MainWindow; 
        win->setAttribute(Qt::WA_DeleteOnClose); 
        win->show(); 
        }); 
        auth->show(); 
        return app.exec(); 
    } 
    
+0

Danke, Ihr Code funktioniert einwandfrei – Dababi