La descarga está en progreso. Por favor, espere

La descarga está en progreso. Por favor, espere

Desarrollador Profesional de Juegos Programación III Unidad I El manejador universal.

Presentaciones similares


Presentación del tema: "Desarrollador Profesional de Juegos Programación III Unidad I El manejador universal."— Transcripción de la presentación:

1 Desarrollador Profesional de Juegos Programación III Unidad I El manejador universal

2 También existe la posibilidad de definir un manejador que pueda capturar cualquier excepción. La sintaxis es la siguiente: catch (...) { } La sentencia catch captura cualquier excepción sin importar el tipo. Existe solamente un catch para el bloque try. Ejemplo: #include using namespace std; bool ok; class Out { }; void foo(bool pvez) { if (pvez) throw Out(); } void test() try { foo(true); } catch(...){ ok = true; } // puede capturar cualquier excepción } int main() { ok = false; test(); return ok ? (cout<<“Excepción capturada",0) : (cout<<“No hay excepción",1); } Salida Excepción capturada

3 Salto a una etiqueta Es posible también utilizar un sentencia goto para transferir el control del programa afuera de un manejador. Vemos el ejemplo visto en el modulo 2 modificado. #include bool ok; class Out { }; // Clase para instanciar el objeto a lanzar void foo(bool pvez); // prototipo de una funcion int main() { try { // bloque try ok = true; foo( true ); } catch( Out o) { // manejador que captura la excepción goto fallo; // salta a la etiqueta fallo } return (cout<<"Acierto!“, 0); fallo:// etiqueta return (cout<<"¡Fallo!“, 1); } void foo(bool pvez){ // definición de la function foo if( pvez ) throw Out(); // Lanza la excepción }

4 Las excepciones pueden ser anidadas a cualquier nivel (existir bloques try dentro de otros bloques try y bloques catch). Para mantener la regla que indica que un bloque try debe ser seguido inevitablemente por un catch, entonces pueden existir secuencias try-catch dentro de bloques try y de bloques catch. Excepciones anidadas Secuencias anidadas en el try. class Error { }; void foo () {... try { // Bloque-intento 1... try { // Bloque-intento en 1.1... } catch { // Handler de 1.1 captura excepciones de 1.1 }... // continúa bloque 1 } catch (Error) { //Handler de 1: captura excepciones de 1 }... // sigue a bloque 1 } Secuencias anidadas en el catch class Error { }; void foo () {... try { // Bloque-intento 1... } catch (Error) { // Handler de 1: captura excepciones de 1 try { // Bloque-intento en Handler-H1... } catch { // Handler de H1.1 captura excepc. de H1.1 }... // continúa handler H1 }... // sigue a bloque 1 }

5 Ejemplo 1: #include class Base{ }; class Derivada1: public Base{ }; class Derivada2: public Base{ }; void foo(int valor); int main() { try { foo(0); } catch(const Derivada1&) { cout<<"Estoy en Derivada 1"<<endl; } catch(const Derivada2&) { cout<<"Estoy en Derivada 2" <<endl; } try { foo(1); } catch(const Derivada1 &) { cout<<"Estoy en Derivada 1"<<endl; } catch(const Derivada2 &) { cout<<"Estoy en Derivada 2"<<endl; } return 0; } void foo(int valor) { if (valor==1) throw( Derivada1() ); else throw( Derivada2() ); } Salida Estoy en Derivada 2 Estoy en Derivada

6 Ejemplo 2: Vemos que cuando se captura una excepción y esta pertenece a una jerarquía de clases, se comienza por la clase más derivada, sino se pierde la capacidad de discriminar el tipo de excepción acontecido. class Base{ }; class Derivada1: public Base{ }; class Derivada2: public Base{ }; void foo( int valor) { switch(valor){ case 1 : throw( Derivada1() ); break; case 2 : throw( Derivada2() ); break; default : throw( Base() ); break; } int main() { try { foo(0); } // estas sentencias están en el orden adecuado catch(const Derivada1&) { cout<<"estoy en Derivada1"; } catch(const Derivada2&) { cout<<"estoy en Derivada2" ; } catch(const Base& ) { cout<<"estoy en Base" ; } try { foo(1); } catch(const Derivada1& ) { cout<<"estoy en Derivada1"; } catch(const Derivada2&) { cout<<"estoy en Derivada2"; } catch(const Base& ) { cout<<"estoy en Base" ; } try { foo(2); } catch(const Derivada1& ){ cout<<"Base de Derivada1"; } catch(const Derivada2&) { cout<<"Base de Derivada2" ; } catch(const Base& ) { cout<<"Base" ; }

7 … try { foo(1); } catch(const Base& ) { cout<<"estoy (en donde??)”; } catch(const Derivada1&) { cout<<"estoy en Derivada1"; } catch(const Derivada2&) { cout<<"estoy en Derivada2" ; } try { foo(2); } catch(const Base& ) { cout<<"estoy (en donde??"; } catch(const Derivada1& ) { cout<<"estoy en Derivada1"; } catch(const Derivada2&) { cout<<"estoy en Derivada2" ; } return 0; } Salida estoy en Base estoy en Derivada1 estoy en Derivada2 estoy (en donde??) estoy (en donde??) /* Si en cambio capturamos a la clase base primero entonces perdemos la posibilidad de testear a la sub-clase de la excepción que se lanzó realmente */

8 Para solucionar el diseño anterior podríamos capturar solamente las excepciones de la clase-base y usar polimorfismo para discriminar la excepción: #include using namespace std; class Base { public: virtual void cartel() { cout << " Estoy en Base" << endl; } }; class Derivada1 : public Base { public: void cartel () { cout << "Estoy en Derivada1" << endl; } }; class Derivada2: public Base { public: void cartel () { cout << "Estoy en Derivada2" << endl; } }; void foo(int valor) { switch(valor){ case 1 : throw( Derivada1() ); break; case 2 : throw( Derivada2() ); break; default : throw( Base() ); break; } // continua

9 int main() { try { foo(0); } catch(Base& f) { f.cartel(); } try { foo(1); } catch(Base& f) { f.cartel(); } try { foo(2); } catch(Base& f) { f.cartel(); } return 0; } Salida Base Estoy en Derivada1 Estoy en Derivada2


Descargar ppt "Desarrollador Profesional de Juegos Programación III Unidad I El manejador universal."

Presentaciones similares


Anuncios Google