Bloque try
de función
Establece un controlador de excepciones alrededor del cuerpo de una función.
Contenido |
[editar]Sintaxis
El bloque try
de función es una de las formas alternativas de sintaxis para el cuerpo de la función, que es una parte de la definición de función.
try inicializador-ctor (opcional)instrucción-compuestasec-de-controladores | |||||||||
inicializador-ctor | - | Lista de inicializadores de miembro, solamente permitida en constructores. |
instrucción-compuesta | - | Secuencia de instrucciones entre llaves que constituyen el cuerpo de una función. |
sec-de-controladores | - | Secuencia de una o más cláusulas catch . |
[editar]Explicación
Un bloque try
de función asocia una secuencia de cláusulas catch
con el cuerpo entero de la función, y también con la lista de inicializadores de miembro (si se usa en un constructor). Cada excepción lanzada desde cualquier instrucción en el cuerpo de la función, o (para constructores), desde cualquier miembro o constructor base, o (para destructores) desde cualquier miembro o destructor base, transfiere el control a la sec-de-controladores de la misma manera en que lo haría una excepción lanzada en un bloque try
regular.
#include <iostream>#include <string> struct S {std::string m; S(conststd::string& str, int idx)try: m(str, idx){std::cout<<"S("<< str <<", "<< idx <<") construido, m = "<< m <<'\n';}catch(conststd::exception& e){std::cerr<<"S("<< str <<", "<< idx <<") falló: "<< e.what()<<'\n';}// "throw;" implícito, aquí para constructor}; int main(){ S s1{"ABC", 1};// no lanza excepción (el índice está en los límites) try{ S s2{"ABC", 4};// lanza excepción (fuera de límites)}catch(std::exception& e){std::cout<<"S s2... causó una excepción: "<< e.what()<<'\n';}}
Antes de que se entre a cualquiera de las cláusulas catch
de un bloque try
de función en un constructor, todos los miembros completamente construidos y las bases ya se han destruido.
Si el bloque | (desde C++11) |
Antes de que se entre a cualquier cláusula catch
de un bloque try
de función en un destructor, todas las bases y los miembros no-variantes ya se destruyeron.
El comportamiento es indefinido si la cláusula catch
del bloque try
de función usado en un constructor o un destructor accede a una base o a un miembro no estático del objeto.
Cada cláusula catch
en el bloque try
de función de un constructor debe terminar lanzando una excepción. Si el control llega al final de tal controlador, la excepción en curso se vuelve a lanzar automáticamente como si lo hubiera sido mediante throw;. La instrucción return
no se permite en ninguna cláusula catch
del bloque try
de función de un constructor.
Al llegar al final de una cláusula catch
de un bloque try
de función de un destructor también se vuelve a lanzar automaticámente la excepción en curso como si lo hubiera sido mediante throw;, pero se permite una instrucción return
.
Para todas las otras funciones, llegar al fin de una cláusula catch
equivale a return; si el tipo de retorno de la función es (que puede estar calificado-cv) void, de otra forma, el comportamiento es indefinido.
[editar]Notas
El propósito principal de los bloques try
de función es responder a una excepción lanzada desde la lista de inicializadores de miembros en un constructor registrando (logging) y volviendo a lanzar, modificar el objeto de excepción y volver a lanzar, lanzar una excepción diferente en su lugar, o terminar el programa. Raramente se usan con destructores o con funciones regulares.
Un bloque try
de función no atrapa las excepciones lanzadas por los constructores de copia/movimiento y los destructores de los parámetros de función pasados por valor: esas excepciones se lanzan en el contexto del llamador.
El bloque try de función de una función de nivel superior de un hilo no atrapa las excepciones lanzadas desde los constructores y destructores de objetos locales al hilo (thread-local ) (excepto para los constructores locales al hilo en el ámbito de función). | (desde C++11) |
De la misma manera, el bloque try
de función de la función main()
no atrapa las excepciones lanzadas desde los constructores y destructores de los objetos estáticos (excepto para los constructores de objetos estáticos locales a la función).
El ámbito y la duración de los parámetros de función (pero no de ningún objeto declarado en la función misma) se extiende hasta el final de la secuencia-de-controladores.
int f(int n =2)try{++n;// incrementa el parámetro de funciónthrow n;}catch(...){++n;// n está en ámbito y todavía se refiere al parámetro de funciónassert(n ==4);return n;}
[editar]Defect reports
Los siguientes informes de defectos de cambio de comportamiento se aplicaron de manera retroactiva a los estándares de C++ publicados anteriormente.
ID | Aplicado a | Comportamiento según lo publicado | Comportamiento correcto |
---|---|---|---|
CWG 1167 | C++98 | no se especifica si un bloque try de función en un destructor capturaráexcepciones de un destructor de base o de miembro | dichas excepciones son capturadas |