En esta página

Seguridad de excepciones

Advertencia preliminar: La seguridad de excepciones no es una característica completa. Los casos comunes deberían funcionar, pero las clases podrían tener fugas o incluso bloquearse.

Qt no lanzará excepciones. En su lugar, se utilizan códigos de error. Además, algunas clases tienen mensajes de error visibles para el usuario, por ejemplo QIODevice::errorString() o QSqlQuery::lastError(). Esto tiene razones históricas y prácticas - activar las excepciones puede incrementar el tamaño de la librería en más de un 20%.

Las siguientes secciones describen el comportamiento de Qt si se activa el soporte de excepciones en tiempo de compilación.

Módulos seguros contra excepciones

Contenedores

Las clases contenedoras de Qt son generalmente neutrales a las excepciones. Pasan cualquier excepción que ocurra dentro de su tipo contenido T al usuario mientras mantienen su estado interno válido.

Ejemplo:

QList<QString> list;
...
try {
    list.append("hello");
} catch (...) {
}
// list is safe to use - the exception did not affect it.

Las excepciones a esta regla son los contenedores para tipos que pueden lanzar durante construcciones de asignación o copia. Para estos tipos, las funciones que modifican el contenedor y devuelven un valor no son seguras:

MyType s = list.takeAt(2);

Si se produce una excepción durante la asignación de s, el valor en el índice 2 ya se ha eliminado del contenedor, pero aún no se ha asignado a s. Se pierde sin posibilidad de recuperación. Se pierde sin posibilidad de recuperación.

La forma correcta de escribirlo:

MyType s = list.at(2);
list.removeAt(2);

Si la asignación falla, el contenedor seguirá conteniendo el valor; no se ha producido ninguna pérdida de datos.

Tenga en cuenta que las clases Qt implícitamente compartidas no lanzarán en sus operadores de asignación o constructores de copia, por lo que la limitación anterior no se aplica.

Manipulación fuera de memoria

La mayoría de los sistemas operativos de escritorio sobrecomprometen memoria. Esto significa que malloc() o operator new devuelven un puntero válido, aunque no haya suficiente memoria disponible en el momento de la asignación. En estos sistemas, no se lanza ninguna excepción del tipo std::bad_alloc.

En el resto de sistemas operativos, Qt lanzará una excepción de tipo std::bad_alloc si falla alguna asignación. Las asignaciones pueden fallar si el sistema se queda sin memoria o no tiene suficiente memoria continua para asignar el tamaño solicitado.

Las excepciones a esta regla están documentadas. Por ejemplo, los constructores de QImage crearán una imagen null si no existe suficiente memoria en lugar de lanzar una excepción.

Recuperación de excepciones

Actualmente, el único caso de uso soportado para recuperarse de excepciones lanzadas dentro de Qt (por ejemplo debido a falta de memoria) es salir del bucle de eventos y hacer alguna limpieza antes de salir de la aplicación.

Caso de uso típico:

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;

Después de que se lance una excepción, la conexión con el servidor de ventanas puede estar ya cerrada. No es seguro llamar a una función relacionada con GUI después de capturar una excepción.

Excepciones en el código cliente

Señales y ranuras

Lanzar una excepción desde una ranura invocada por el mecanismo de conexión señal-ranura de Qt se considera un comportamiento indefinido, a menos que se maneje dentro de la ranura:

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 la ranura se invoca directamente, como una llamada a una función normal, se pueden utilizar excepciones. Esto se debe a que el mecanismo de conexión se omite cuando se invocan ranuras directamente:

State state; StateListener stateListener;// ...try { // OK; invocando el slot directamente.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.