La descarga está en progreso. Por favor, espere

La descarga está en progreso. Por favor, espere

Excepciones Las excepciones son señales (en forma de objeto) que se generan en ejecución en casos de errores, para que puedan ser gestionadas en el programa.

Presentaciones similares


Presentación del tema: "Excepciones Las excepciones son señales (en forma de objeto) que se generan en ejecución en casos de errores, para que puedan ser gestionadas en el programa."— Transcripción de la presentación:

1 Excepciones Las excepciones son señales (en forma de objeto) que se generan en ejecución en casos de errores, para que puedan ser gestionadas en el programa. Son un mecanismo para el tratamiento de errores alternativo a los condicionales y las funciones booleanas. Las excepciones se clasifican por tipos formando jerarquías de clases de excepciones. Además, normalmente transmiten un mensaje indicando el error ocurrido. En C++ estándar, la raíz de la jerarquía es exception. En C++ Builder, la raíz de la jerarquía es Exception.

2 Excepciones Las excepciones pueden ser controladas por el programador. Se pueden lanzar y capturar. Cuando se genera (se lanza o eleva) una excepción, se transmite automáticamente a través de la pila de llamadas a funciones hasta que es tratada (capturada o interceptada). Las excepciones deben de tratarse procurando que la aplicación pueda seguir ejecutándose con el menor daño posible, o si no terminando la ejecución del programa. En general, la función que lanza la excepción puede estar en una determinada unidad o librería, y el código que la trata en otra.

3 Excepciones: Ejemplo La función StrToInt(AnsiString) genera una excepción si la cadena que recibe por parámetro no representa sintácticamente un entero válido. Así StrToInt("12.9") o StrToInt("12a") generan una excepción del tipo EConvertError que indica que no se puede convertir el AnsiString a un valor entero. Por tanto, al utilizar esta función deberíamos tener en cuenta esta posibilidad cuando no estemos seguros de que la cadena es válida, como cuando la cadena es un dato que se pide al usuario.

4 Excepciones: Lanzamiento Para lanzar una excepción: throw ConstructoraClase(Argumentos); throw crea un objeto del tipo indicado invocando a la constructora.

5 Excepciones: Lanzamiento class ExcepFich{ public: AnsiString mensaje; ExcepFich(AnsiString m){mensaje=m;} }; virtual void cargar(ifstream& fich){ string cadena; fich >> cadena; if (cadena!=\\Xini) throw ExcepFich(Error de lectura); else.... }

6 Excepciones: Sintaxis En el.h se deben indicar que métodos van a lanzar excepciones y de qué tipo van a ser éstas. Tipo nombreMetodo(argumentos) throw (A,B,C,...); A,B,C,.. son nombres de clases. En el.cpp: Tipo nombreMetodo(argumentos) throw (A,B,C,...){..}; Si no se pone nada puede lanzar excepciones de cualquier tipo.

7 Excepciones: Sintaxis En el.h: virtual void cargar(ifstream& fich) throw (ExcepFich); En el.cpp: void Linea::cargar(ifstream& f) throw (ExcepFich) {.....};

8 Excepciones: Captura y control try { // código que puede generar excepciones } catch (Clase 1 [& Var 1 ]) {// tratamiento de excepciones de tipo Clase 1 } catch (Clase 2 [& Var 2 ]) {// tratamiento de excepciones de tipo Clase 2 }..... catch (Clase N [& Var N ]) {// tratamiento de excepciones de tipo Clase N }

9 Excepciones: Captura y control Según se va subiendo por la pila de llamadas en busca de bloques try, sus correspondientes cláusulas catch se prueban secuencialmente en busca de una concordancia. Mientras no se encuentre la concordancia, seguimos subiendo por la pila de llamadas. Una concordancia se da cuando la excepción lanzada es una instancia directa o indirecta (subclase) de la especificada en el parámetro del catch. La siguiente instrucción a un bloque try-catch es la siguiente instrucción que aparece después de todos las cláusulas catch.

10 Excepciones: Captura y control class Error{}; // p1 y q1 no hacen nada void principal(){ try {p1(); p2();p3(); } catch (Error) {ShowMessage(Capturada en principal");} ShowMessage("Sigo ejecutando por aquí (principal)");} void p2(){ p1(); try {q1();q2();q3();} catch (Error) {ShowMessage("Capturada en p2");} ShowMessage("Sigo ejecutando por aquí (p2)");}; void p3(){ ShowMessage(Si que ejecuto p3");}; void q2(){try {throw Error();} catch (Error){ShowMessage("Capturada en q2");}; ShowMessage("Sigo ejecutando por aquí (q2)"); } void q3(){ ShowMessage(Si que ejecuto q3");};

11 Excepciones: Captura y control Se muestra por pantalla: Capturada en q2 Sigo ejecutando por aquí (q2) Si ejecuto q3 Sigo ejecutando por aquí (p2) Si ejecuto p3 Sigo ejecutando por aquí (principal)

12 Excepciones: Captura y control class Error{}; class Error1{};// p1 y q1 no hacen nada void principal(){ try {p1(); p2();p3(); } catch (Error) {ShowMessage(Capturada en principal");} ShowMessage("Sigo ejecutando por aquí (principal)");} void p2(){ p1(); try {q1();q2();q3();} catch (Error) {ShowMessage("Capturada en p2");} ShowMessage("Sigo ejecutando por aquí (p2)");}; void p3(){ ShowMessage(Si que ejecuto p3");}; void q2(){try {throw Error();} catch (Error1) {ShowMessage("Capturada en q2");}; ShowMessage("Sigo ejecutando por aquí (q2)"); }

13 Excepciones: Captura y control Entonces: Capturada en p2 Sigo ejecutando por aquí (p2) Si ejecuto p3 Sigo ejecutando por aquí (principal)

14 Excepciones: Captura y control class Error{}; class Error1{}; void principal(){ try {p1(); p2();p3(); } catch (Error) {ShowMessage(Capturada en principal");} ShowMessage("Sigo ejecutando por aquí (principal)");} void p2(){ p1(); try {q1();q2();q3();} catch (Error1) {ShowMessage("Capturada en p2");} ShowMessage("Sigo ejecutando por aquí (p2)");}; void q2(){try {throw Error();} catch (Error1) {ShowMessage("Capturada en q2");}; ShowMessage("Sigo ejecutando por aquí (q2)"); }

15 Excepciones: Captura y control void q1(){ try {} catch (Error){ShowMessage("Capturada en q1");} ShowMessage("Sigo ejecutando por aquí (q1)"); }; void p1(){ try {} catch (Error) {ShowMessage("Capturada en p1");} ShowMessage("Sigo ejecutando por aquí (p1)"); };

16 Excepciones: Captura y control Entonces: Sigo ejecutando por aquí (p1) Sigo ejecutando por aquí (q1) Capturada en principal Sigo ejecutando por aquí (principal)

17 Excepciones: Captura y control class Error{}; void principal(){ try {p2(); p3();} catch (Error){ShowMessage(Capturada en principal");} ShowMessage("Sigo ejecutando por aquí (principal)");} void p2(){ p1(); try {q1();q2();q3();} catch (Error){ShowMessage("Capturada en p2");} ShowMessage("Sigo ejecutando por aquí (p2)");}; void p1(){ throw Error();}

18 Excepciones: Captura y control Capturada en principal Sigo ejecutando por aquí (principal)

19 Excepciones: Captura y control Cuando creamos una aplicación nueva, las excepciones que no sean capturadas por el programador, siempre son controladas por la aplicación: Por las propias librerías gráficas. O por la aplicación (en caso de excepciones propias del Builder).

20 Excepciones: Captura y control WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { try { Application->Initialize(); Application->CreateForm(__classid(TForm1), &Form1); Application->Run(); } catch (Exception &exception) // excepciones del Builder { Application->ShowException(&exception); } return 0; }

21 Excepciones: Captura y control Cuando se captura una excepción, el objeto de la excepción es destruido. En una cláusula catch se puede declarar una variable local ([&Var]) cuyo ámbito es el bloque del tratamiento. Como es un objeto, podemos hacer con él lo que con cualquier otro objeto de esa clase. En una cláusula catch se puede volver a lanzar la misma excepción mediante throw. Para capturar cualquier tipo de excepción: catch(...){//tratamiento}

22 Excepciones: Captura y control void TForm1::p1(){ try{ p2();} catch (const Error& E){ ShowMessage(E.mensaje); ShowMessage("Capturada en principal");}}; // void TForm1::p2(){ try{ p3();} catch (...){throw;} }; // void TForm1::p3(){ try{ p4();} catch(...){throw;}}; // void TForm1::p4(){ throw Error("lanzada excepcion en p4");};

23 Excepciones: La clase Exception C++Builder contiene muchas clases predefinidas para lanzar excepciones. Todas ellas derivan de la clase Exception. Para capturar una excepción de la clase Exception o de alguna de sus derivadas hay que usar la sintaxis: catch (const Exception &Variable) Una de las distintas constructoras de Exception es: Exception(const AnsiString Msg);

24 Excepciones: La clase Exception Podemos por tanto lanzar este tipo de excepciones con: throw Exception( ); Cuando las capturamos vía un: catch (const Exception &Variable) Podemos acceder a su mensaje utilizando la propiedad Message: Variable.Message

25 Excepciones: La clase Exception Si ha sido el propio sistema el que ha lanzado la excepción, también podemos capturar el mensaje que contiene. En este caso el mensaje es el nombre de una subclase de Exception (el tipo del objeto excepción lanzado). Entre la subclases de Exception destacamos: EAccessViolation : Acceso de memoria incorrecto. EConvertError : Error de conversión de tipos. EDivByZero : división entre cero. EInOutError : Error de Entrada/salida. En la ayuda pueden encontrarse todas.

26 Excepciones: La clase Exception void p() { throw Exception(excepción provocada); } void principal() { try {p();} catch (const Exception &E){ShowMessage(E.Message);} } Se captura la excepción lanzada por p() y se muestra el mensaje excepción provocada

27 Excepciones: La clase Exception void p() { int n1=5; int n2=0; int n3=n1/n2; // lanza una excepción de división entre 0 } void principal() { try {p();} catch (const Exception &E){ShowMessage(E.Message);} } Se captura la excepción lanzada por p() y se muestra el mensaje EDivByZero

28 Excepciones: La clase Exception void p() { int n1=5; int n2=0; int n3=n1/n2; // lanza una excepción de división entre 0 } void principal() { try {p();} catch (const EDivByZero &E ){ShowMessage(división entre 0);} } Se captura la excepción lanzada por p() y se muestra el mensaje división entre 0

29 Excepciones: Un ejemplo

30 Tipos de errores que pueden aparecer: Errores de conversión de tipos (de String a Entero). División entre 0

31 Excepciones: Un ejemplo void __fastcall TForm1::BotonOKClick(TObject *Sender) { try { int n1=StrToInt(EditPrimerEntero->Text); int n2=StrToInt(EditSegundoEntero->Text); ShowMessage(n1/n2); Close(); } catch (const EConvertError &E) {ShowMessage("Error de conversión"); } catch (const EDivByZero &E) {ShowMessage("División entre 0");} }

32 Excepciones: Un ejemplo Se hace un mal control de los posibles errores ya que no se muestra información sobre el dato que ha sido mal introducido. ¿Qué pasaría si tuviéramos 100 datos para introducir? ¡¡¡¡ Sería razonable lanzar la excepción en cuanto se detecte que un dato ha sido mal introducido !!!!

33 Excepciones: Un ejemplo void __fastcall TForm1::BotonOKClick(TObject *Sender) { try { int n1=StrToInt(EditPrimerEntero->Text); continuaPidiendoDatos(n1); } catch (const EConvertError &E) {ShowMessage("Meta un entero como primer entero"); ActiveControl=EditPrimerEntero; EditPrimerEntero->Text=""; LabelPrimerEntero->Font->Color=clBlue;} }

34 Excepciones: Un ejemplo void TForm1::continuaPidiendoDatos(int n1) { try { LabelPrimerEntero->Font->Color=clBlack; int n2=StrToInt(EditSegundoEntero->Text); if (n2==0) throw EDivByZero ("El segundo entero NO puede ser 0"); else {LabelSegundoEntero->Font->Color=clBlack; ShowMessage(n1/n2); Close(); }

35 Excepciones: Un ejemplo catch (EConvertError &E) { ShowMessage("Meta un entero como segundo entero"); ActiveControl=EditSegundoEntero; EditSegundoEntero->Text=""; LabelSegundoEntero->Font->Color=clBlue; } catch (const EDivByZero &E) { ShowMessage(E.Message); ActiveControl=EditSegundoEntero; EditSegundoEntero->Text=""; LabelSegundoEntero->Font->Color=clBlue;}}}

36 Excepciones: Último ejemplo for (int i=0; i


Descargar ppt "Excepciones Las excepciones son señales (en forma de objeto) que se generan en ejecución en casos de errores, para que puedan ser gestionadas en el programa."

Presentaciones similares


Anuncios Google