Sécurité des exceptions
Avertissement préliminaire: La sécurité contre les exceptions n'est pas une fonctionnalité complète ! Les cas courants devraient fonctionner, mais les classes peuvent encore présenter des fuites, voire se bloquer.
Qt lui-même ne lance pas d'exceptions. Au lieu de cela, des codes d'erreur sont utilisés. En outre, certaines classes ont des messages d'erreur visibles par l'utilisateur, par exemple QIODevice::errorString() ou QSqlQuery::lastError(). Cela s'explique par des raisons historiques et pratiques : l'activation des exceptions peut augmenter la taille de la bibliothèque de plus de 20 %.
Les sections suivantes décrivent le comportement de Qt si la prise en charge des exceptions est activée au moment de la compilation.
Modules à l'abri des exceptions
Conteneurs
Les classes de conteneurs de Qt sont généralement neutres vis-à-vis des exceptions. Elles transmettent à l'utilisateur toute exception survenant dans le type qu'elles contiennent T, tout en conservant leur état interne.
Exemple :
QList<QString> list; ... try { list.append("hello"); } catch (...) { } // list is safe to use - the exception did not affect it.
Les exceptions à cette règle sont les conteneurs pour les types qui peuvent être lancés pendant les constructions d'affectation ou de copie. Pour ces types, les fonctions qui modifient le conteneur et renvoient une valeur ne sont pas sûres :
MyType s = list.takeAt(2);
Si une exception se produit pendant l'affectation de s, la valeur à l'index 2 est déjà retirée du conteneur, mais n'a pas encore été affectée à s. Elle est perdue sans possibilité de récupération.
La façon correcte de l'écrire :
MyType s = list.at(2); list.removeAt(2);
Si l'assignation est rejetée, le conteneur contiendra toujours la valeur ; il n'y a pas eu de perte de données.
Notez que les classes Qt implicitement partagées ne jetteront pas dans leurs opérateurs d'affectation ou leurs constructeurs de copie, de sorte que la limitation ci-dessus ne s'applique pas.
Gestion des données hors mémoire
La plupart des systèmes d'exploitation de bureau surchargent la mémoire. Cela signifie que malloc() ou operator new renvoient un pointeur valide, même s'il n'y a pas assez de mémoire disponible au moment de l'allocation. Sur ces systèmes, aucune exception de type std::bad_alloc n'est levée.
Sur tous les autres systèmes d'exploitation, Qt lèvera une exception de type std::bad_alloc si une allocation échoue. Les allocations peuvent échouer si le système manque de mémoire ou n'a pas assez de mémoire continue pour allouer la taille demandée.
Les exceptions à cette règle sont documentées. Par exemple, les constructeurs de QImage créeront une image null s'il n'y a pas assez de mémoire au lieu de lever une exception.
Récupération des exceptions
Actuellement, le seul cas d'utilisation pris en charge pour la récupération des exceptions lancées dans Qt (par exemple en raison d'un manque de mémoire) est de quitter la boucle d'événements et de faire un peu de nettoyage avant de quitter l'application.
Cas d'utilisation typique :
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;
Après le déclenchement d'une exception, la connexion au serveur de fenêtrage peut déjà être fermée. Il n'est pas sûr d'appeler une fonction liée à l'interface graphique après avoir attrapé une exception.
Exceptions dans le code du client
Signaux et emplacements
Lancer une exception à partir d'un slot invoqué par le mécanisme de connexion signal-slot de Qt est considéré comme un comportement indéfini, à moins qu'elle ne soit gérée dans le slot :
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()));
Si le slot est invoqué directement, comme un appel de fonction normal, des exceptions peuvent être utilisées. En effet, le mécanisme de connexion est contourné lors de l'invocation directe des slots :
State state ; StateListener stateListener ;// ...try { // OK ; invocation directe du slot.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.