Qt Objekte erzeugen



  • Hallo,

    ich hätte mal ein Frage bezüglich des erzeugens von Objekten, im speziellen Fall von Dialogen. Ich habe mir schon von einigen Open Source Programmen den Quelltext angesehen. Und bis jetzt habe ich immer folgende ähnliche Konstrukte gefunden

    void MainWindow::showDialog() {
        QDialog *MyDialog = new QDialog(this);
        MyDialog->exec();
        delete pDialog;
    }
    

    was aber wenn der Dialog aus irgendwelchen Gründen nicht erzeugt werden kann und der Pointer ungültig ist? Ich würde es so lösen:

    void MainWindow::showDialog() {
        QDialog *MyDialog = new QDialog(this);
        if (pDialog) {
            MyDialog->exec();
            delete pDialog;
        }
    }
    

    Würde es der Sicherheit wegen nicht mit einem std::auto_ptr ähnlichen Konstrukt besser sein?

    void MainWindow::showDialog() {
        QScopedPointer<MyDialog> pDialog(new MyDialog(this));
        if(!pDialog.isNull()) {
            pDialog->exec();
        }
    }
    

    Das ist jetzt mit Absicht wirklich sehr minimal gehalten. Mir geht es wirklich nur um die Frage, was passiert bei Qt wenn beim Erzeugen von z.B. eines Dialogs ein Fehler auftritt, oder allgemein bei einer Exception. Muß auch dazu sagen, das ich mich mit dem Exception Handlich von Qt noch nicht wirklich auseinandergesetzt haben.

    Würde mich freuen wenn da jemand etwas konstruktives dazu schreiben könnte.

    Grüße Netzschleicher



  • Dir ist schon klar, dass Qt eine eigenes Speicherverwaltungskonzept hat? Wenn ein QObject gelöscht wird, löscht es auch seine Kinder. Du übergibst dem QDialog Konstruktor this, d.h. der Dialog ist ein Kindobjekt von deinem Mainwindow und wenn das gelöscht wird, wird auch der Dialog gelöscht. D.h., den bräuchtest du theoretisch gar nicht löschen. Würde ich in dem Fall nicht machen, aber das sollte dir beim Benutzen von Qt klar sein.
    Eigentlich brauchst du hier gar kein delete, du kannst den QDialog auch auf dem Stack anlegen, das wär hier aus meiner Sicht die beste Variante. Sonst kannst du auch auto_ptr oder unique_ptr verwenden. QScopedPointer hab ich noch nie verwendet, dafür gibts std::unique_ptr oder vor C++11 boost::scoped_ptr.

    Qt schmeißt keine Exceptions. Deine Prüfung auf 0 macht auch keinen Sinn. new kann nicht 0 zurückgeben. Wenn der Speicher nicht reicht, fliegt eine std::bad_alloc Exception. Die fängst du hier nicht ab also kann auch deine Prüfung auf 0 nichts bringen. Oder wenn der Konstruktor sonst irgendeine Exception schmeißen würde (macht Qt selber wie gesagt nicht), würdest du sie damit natürlich auch nicht fangen.



  • Das der Dialog, dadurch das ich diesen als Kindobjekt des Mainwindow erzeugt habe, gelöscht wird sobald das Mainwindow beendet wird, ist mir schon klar. Ich würde diesen eben in der Funktion löschen, einfach das nach dem Beenden des Dialogs der Speicher gleich freigegeben wird und nicht erst beim Beenden des Mainwindow (also des Programmes an sich).

    Du meinst solch ein Konstrukt?

    MyDialog Dialog;
    Dialog.exec();
    

    War eben bis jetzt so geimpft, solche Objekte auf dem Heap anzulegen und nicht auf dem Stack. Ich weis auch das ich bei Qt noch ganz am Anfang stehe. Aber versuche so viel Zeit wie möglich dran zu sein. 🙂



  • Eher so:

    MyDialog Dialog(this);
    Dialog.exec();
    

    Also, auch wieder this als Parameter übergeben. Sonst hat das Fenster keinen Owner und bekommt unter Windows dann z.B. einen eigenen Eintrag in der Taskleiste.

    Ich seh kein Problem damit, den Dialog auf dem Stack anzulegen. Du musst nur aufpassen, dass er nicht irgendwo wieder als Parameter reingegeben wird.



  • Ja, das 'this' hatte gefehlt. Hab ich inzwischen so auch mal versucht, natürlich mit dem 'this'.
    Mich hate es dann auch mal interessiert was der Dialog auf dem Stack an Speicher verbraucht.
    Habe mir das dann mal mit

    QString::number(sizeof(Dialog))
    

    anzeigen lassen. Es wurde mir 24Bytes angezeigt, also für heutige Verhältnisse nicht wirklich viel.

    Der Dialog taucht sonst nirgends anders auf, nur in der Funktion, welche als SLOT für das Anklicken eines Menüeintrages dient.



  • So gut wie alle Qt Klassen verwenden das pimpl Idiom, haben also nur einen Zeiger auf die interne Implementierung.


Anmelden zum Antworten