Ausnahmensicherheit
Vorläufiger Hinweis: Die Ausnahmensicherheit ist noch nicht vollständig implementiert! Gängige Anwendungsfälle sollten funktionieren, aber es kann dennoch zu Speicherlecks oder sogar zu Abstürzen kommen.
Qt selbst löst keine Ausnahmen aus. Stattdessen werden Fehlercodes verwendet. Darüber hinaus verfügen einige Klassen über für den Benutzer sichtbare Fehlermeldungen, zum Beispiel QIODevice::errorString() oder QSqlQuery::lastError(). Dies hat historische und praktische Gründe – das Aktivieren von Ausnahmen kann die Bibliotheksgröße um über 20 % erhöhen.
In den folgenden Abschnitten wird das Verhalten von Qt beschrieben, wenn die Unterstützung für Ausnahmen zur Kompilierungszeit aktiviert ist.
Ausnahmensichere Module
Container
Die Containerklassen von Qt sind im Allgemeinen ausnahmeneutral. Sie leiten jede Ausnahme, die innerhalb ihres enthaltenen Typ- T auftritt, an den Benutzer weiter, während ihr interner Zustand gültig bleibt.
Beispiel:
QList<QString> list;
...
try {
list.append("hello");
} catch (...) {
}
// list is safe to use - the exception did not affect it.Ausnahmen von dieser Regel bilden Container für Typen, die während der Zuweisung oder beim Kopieren Ausnahmen auslösen können. Bei diesen Typen ist die Verwendung von Funktionen, die den Container verändern und gleichzeitig einen Wert zurückgeben, unsicher:
MyType s = list.takeAt(2);Tritt während der Zuweisung von ` s` eine Ausnahme auf, ist der Wert am Index 2 bereits aus dem Container entfernt worden, wurde aber noch nicht ` s ` zugewiesen. Er geht unwiederbringlich verloren.
Die korrekte Schreibweise lautet:
MyType s = list.at(2);
list.removeAt(2);Wenn bei der Zuweisung eine Ausnahme ausgelöst wird, enthält der Container den Wert weiterhin; es ist kein Datenverlust aufgetreten.
Beachten Sie, dass implizit gemeinsam genutzte Qt-Klassen in ihren Zuweisungsoperatoren oder Kopierkonstruktoren keine Ausnahmen auslösen; daher gilt die oben genannte Einschränkung nicht.
Behandlung von Speicherplatzmangel
Die meisten Desktop-Betriebssysteme weisen mehr Speicher zu, als tatsächlich vorhanden ist. Das bedeutet, dass die Funktionen ` malloc() ` oder ` operator new ` einen gültigen Zeiger zurückgeben, auch wenn zum Zeitpunkt der Zuweisung nicht genügend Speicher verfügbar ist. Auf solchen Systemen wird keine Ausnahme vom Typ ` std::bad_alloc ` ausgelöst.
Auf allen anderen Betriebssystemen löst Qt eine Ausnahme vom Typ `std::bad_alloc` aus, wenn eine Zuweisung fehlschlägt. Zuweisungen können fehlschlagen, wenn dem System der Speicher ausgeht oder nicht genügend zusammenhängender Speicher zur Verfügung steht, um die angeforderte Größe zuzuweisen.
Ausnahmen von dieser Regel sind dokumentiert. Beispielsweise erstellen die Konstruktoren von ` QImage ` ein ` null `-Bild, wenn nicht genügend Speicher vorhanden ist, anstatt eine Ausnahme auszulösen.
Wiederherstellung nach Ausnahmen
Derzeit ist der einzige unterstützte Anwendungsfall für die Behandlung von in Qt ausgelösten Ausnahmen (beispielsweise aufgrund von Speichermangel) das Verlassen der Ereignisschleife und das Durchführen einiger Aufräummaßnahmen vor dem Beenden der Anwendung.
Typischer Anwendungsfall:
QApplication app(argc, argv);
...
int ret;
try {
ret = app.exec();
} catch (const std::bad_alloc &) {
// clean up here, e.g. save the session
// and close all config files.
return EXIT_FAILURE; // exit the application
}
...
return ret;Nachdem eine Ausnahme ausgelöst wurde, ist die Verbindung zum Fenster-Server möglicherweise bereits geschlossen. Es ist nicht sicher, nach dem Abfangen einer Ausnahme eine GUI-bezogene Funktion aufzurufen.
Ausnahmen im Client-Code
Signale und Slots
Das Auslösen einer Ausnahme aus einem Slot, der über den Signal-Slot- Verbindungsmechanismus von Qt aufgerufen wird, gilt als undefiniertes Verhalten, es sei denn, dies wird innerhalb des Slots abgefangen:
State state;
StateListener stateListener;
// OK; the exception is handled before it leaves the slot.
QObject::connect(&state, SIGNAL(stateChanged()), &stateListener, SLOT(throwHandledException()));
// Undefined behaviour; upon invocation of the slot, the exception will be propagated to the
// point of emission, unwinding the stack of the Qt code (which is not guaranteed to be exception safe).
QObject::connect(&state, SIGNAL(stateChanged()), &stateListener, SLOT(throwUnhandledException()));Wurde der Slot direkt aufgerufen, wie bei einem normalen Funktionsaufruf, dürfen Ausnahmen verwendet werden. Dies liegt daran, dass der Verbindungsmechanismus beim direkten Aufruf von Slots umgangen wird:
State state;
StateListener stateListener;
// ...
try {
// OK; direkter Aufruf des Slots.
stateListener.throwException();
} catch (...) {
qDebug() << "Handling exception not caught in slot.";
}© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.