TUTORIAL: C + + Excepciones

  • spork
  • Brewmaster
  • Silver Member
  • Avatar de Usuario
  • Registrado: Sep 22, 2003
  • Mensajes: 6128
  • Loc: Seattle, WA
  • Status: Offline

Nota Marzo 19th, 2008, 10:52 pm

Introducción


Nota: Este tutorial asume un conocimiento básico del lenguaje C + +. Usted debe saber cómo utilizar las funciones, variables y tener un conocimiento básico de cómo las clases de trabajo.

Nota: El código fuente completo de los ejemplos de este tutorial puede ser descargado al final del tutorial.

En este tutorial, vamos a cubrir los aspectos básicos de manejo de excepciones en C + +. Así también el tacto sobre cómo crear y utilizar sus propias excepciones en sus aplicaciones, así como la manera de tratar con las excepciones lanzadas por STL (Standard Template Library) clases.


Referencia Rápida


Esto es para personas que ya están familiarizados con objeto de excepción en otros lenguajes orientados y simplemente necesitan conocer la sintaxis para el uso de excepciones en C + +. Si usted está llenando este tutorial, por favor pase a la siguiente sección, "¿Qué es una excepción?"

Una excepción:
CPP Código: [ Select ]
void someFunction() throw( int, MyException ) {
    throw 5;
    // or
    throw MyException();
}
  1. void someFunction() throw( int, MyException ) {
  2.     throw 5;
  3.     // or
  4.     throw MyException();
  5. }


La captura de excepciones:
CPP Código: [ Select ]
try {
    someFunction();
}
catch( int ie ) {
    cout << "Caught an int: " << e << endl;
}
catch( MyException& me ) {
    cout << "Exception: " << me.getMessage() << endl;
}
catch( ... ) {
    cout << "Caught an unknown exception." << endl;
}
  1. try {
  2.     someFunction();
  3. }
  4. catch( int ie ) {
  5.     cout << "Caught an int: " << e << endl;
  6. }
  7. catch( MyException& me ) {
  8.     cout << "Exception: " << me.getMessage() << endl;
  9. }
  10. catch( ... ) {
  11.     cout << "Caught an unknown exception." << endl;
  12. }


Cómo volver a lanzar una excepción:
CPP Código: [ Select ]
try {
    someFunction();
}
catch( MyException& me ) {
    rethrow me;
}
catch( ... ) {
    rethrow;
}
  1. try {
  2.     someFunction();
  3. }
  4. catch( MyException& me ) {
  5.     rethrow me;
  6. }
  7. catch( ... ) {
  8.     rethrow;
  9. }



¿Qué es una excepción?


Una excepción es un valor que se produce por una parte de un programa cuando se produce una situación excepcional. Normalmente, las excepciones se usan para indicar que una inesperada, pero planificado, ha producido un error y debe ser tratado por una parte diferente del programa.

Por ejemplo, un conector de red podría ser el mantenimiento de una conexión a un host remoto, cuando la conexión se terminó inesperadamente. El programa, por supuesto, debe seguir funcionando, pero hay que tratar con el hecho de que el enchufe ya no es utilizable. El conector puede lanzar una excepción, que será capturado por una parte superior de la palanca del programa, que se ocupará de la situación de forma adecuada, por ejemplo, mediante la creación de un nuevo socket o notificación al usuario.

El es un poco de terminología comunes relacionados con las excepciones que deben familiarizarse con. Echemos un vistazo a los tres más comunes C + + palabras clave utilizadas con excepciones:

intentar - Usamos un bloque de tratar de rodear las partes de código que puede generar excepciones. Esta sección de código es especialmente examinados durante la ejecución para observar las excepciones que puedan haber sido lanzada por las llamadas a funciones dentro del bloque try.

coger - Cada bloque try generalmente tienen uno o más bloques de captura que le sigue. Un bloque catch contiene código que debe ser ejecutado cada vez que se detecta una excepción de un tipo específico. Esto nos permite personalizar el comportamiento de nuestro programa sobre la base de qué tipo de cosas pueden ir mal.

tirar - Esta palabra clave sirve a dos propósitos. Cuando se utiliza dentro del cuerpo de una función, que se utiliza para lanzar una excepción, se lleva hasta la pila de llamadas. Cuando se utiliza en el encabezado de una función, que se utiliza para especificar qué tipo de excepciones, la función puede lanzar.

volver a lanzar - Lo usamos para tomar una excepción que hemos atrapado en un bloque catch y tirar para arriba la pila de llamadas. Esto es normalmente usado cuando la función no tiene la capacidad de tratar con la excepción y debe pasar en la excepción a la siguiente función en la pila.

Una descripción completa de lo que la pila de llamadas es y cómo funciona está fuera del alcance de este tutorial. Para facilitar este tutorial, sin embargo, malos describir brevemente el concepto.

En pocas palabras, cada función que es llamada en C + + tiene todas sus variables locales y la información puesto una zona especial de memoria denominada la pila. Como puede haber adivinado, los datos en este ámbito es añadir y suprimir de la misma manera como las cosas se quitan y de una pila común estructura de datos. Cada vez que una función se llama, se coloca en la pila. Una vez que la función retorna, es eliminado de la pila. Main () siempre será la primera función se añade a la pila y el último eliminado.

Cuando se produce una excepción por la función actual, se pasa a la siguiente función en la pila. Esta función se debe tratar con la excepción, ya sea por gracia a través de la manipulación de un bloque catch, o se lleva hasta la pila de llamadas a su función de llamada. En el caso de la segunda situación, la excepción seguirá extendiéndose hasta la pila hasta que llega a una función que puede alcanzar con éxito y hacer frente a la excepción. Si no hay función controla la excepción, se llegan a main (). Si main () no captura y tratar con la excepción, el programa terminará.


Lanzamiento de excepciones


Ahora que sabes lo que es una excepción, veamos cómo lanzar excepciones en nuestras propias funciones. Echa un vistazo a el siguiente ejemplo:

CPP Código: [ Select ]
void doSomething() {
   
    throw std::string( "Error: something went wrong" );
}
  1. void doSomething() {
  2.    
  3.     throw std::string( "Error: something went wrong" );
  4. }


Esta función simple, doSomething () , Está bien inútil, pero sirve como un ejemplo básico de cómo lanzar una excepción. Observe que la tirar palabra clave se utiliza para realmente producir la excepción. En este punto, la ejecución del programa se detendrá en esa línea, y la excepción será lanzado hasta la pila de llamadas a cualquier función invocada doSomething () . Le corresponde entonces a esa función para hacer frente a la excepción, que pronto veremos.

Otra cosa importante a tener en cuenta es el objeto de ser lanzados. En este ejemplo, estamos lanzando una cadena como nuestro excepción. Pero no se limitan a este, de hecho, puede arrojar datos de prácticamente cualquier tipo como una excepción. Algunos tipos de trabajo mucho mejores que otros, y en un momento y mirar las ventajas y desventajas de utilizar diferentes tipos de excepciones.

Ahora, obviamente, nunca escribir una función similar a la anterior, por lo que le permite mirar a un uso algo más plausible de una excepción:

CPP Código: [ Select ]
float squareRoot( float num ) {
   
    float result = 0;
   
    if( num < 0 ) {
        throw std::string(
            "Error: number must not be negative" );
    }
   
    result = sqrt( num );
   
    return result;
}
  1. float squareRoot( float num ) {
  2.    
  3.     float result = 0;
  4.    
  5.     if( num < 0 ) {
  6.         throw std::string(
  7.             "Error: number must not be negative" );
  8.     }
  9.    
  10.     result = sqrt( num );
  11.    
  12.     return result;
  13. }


Esta función, squareRoot , Tiene un número de punto flotante y devuelve la raíz cuadrada de la misma.

Nota: sqrt () es una función en la biblioteca de matemáticas C, y puede ser utilizado por <cmath> incluida la cabecera.

Ahora bien, ya que no podemos calcular la raíz cuadrada de un número negativo, se debe lanzar una excepción si un número negativo se pasa a la función. En este caso, lanzamos una cadena de nuevo para que podamos utilizar la excepción como un mensaje de error.

Tenga en cuenta que no es necesario poner el cálculo real, resultado = sqrt (num); , En un else if bloque. Esto es porque si el número es negativo, la excepción será lanzada, y la ejecución dentro de la función se detendrá. La excepción será lanzado, y la ejecución del programa será transferido a la función de llamada para hacer frente a la excepción.


¿Qué puede ser lanzado?


Como he dicho antes, prácticamente cualquier tipo de datos en C + + puede ser lanzado como una excepción. Por ejemplo, nos podría fácilmente haber lanzado un número entero en nuestra doSomething () ejemplo:

CPP Código: [ Select ]
void doSomething() {
   
    throw 5;
}
  1. void doSomething() {
  2.    
  3.     throw 5;
  4. }


O bien, podríamos haber lanzado, por ejemplo, un valor booleano:

CPP Código: [ Select ]
void doSomething() {
   
    bool someVariable = false;
    throw someVariable;
}
  1. void doSomething() {
  2.    
  3.     bool someVariable = false;
  4.     throw someVariable;
  5. }


Ambas son igualmente válidas y se ejecutará sin problemas. Pero el problema con el uso de tipos de datos primitivos como excepciones, es que ofrecen muy poca información sobre cuál es el error que realmente ocurrió. Cuando una excepción, es útil para poder incluir información sobre lo que realmente ha fallado en nuestra aplicación: el contexto, el Estado, información extra, etc.

Incluso cadenas de lanzamiento (C-estilo o STL, no importa) no es la mejor solución. La excepción ideal sería capaz de contener todo tipo de información que especifica, sin limitarnos a la estructura lineal de una cadena. ¿Qué hacemos normalmente? Crear una clase .

Recuerde que cualquier tipo de datos en C + + puede ser lanzado como una excepción, y esto incluye cualquier tipo de datos que creamos. Por lo tanto, podemos crear clases para representar a nuestro excepciones, y estas clases pueden contener tanta o tan poca información como nos gusta, estructurado sin embargo nos gusta.

Echemos un vistazo a una clase de excepción simple, CustomException, que demuestra esto:

CPP Código: [ Select ]
class CustomException {
 
private:
   
    std::string message;
 
public:
    CustomException( std::string message );
    inline std::string getMessage() { return message; };
 
};
  1. class CustomException {
  2.  
  3. private:
  4.    
  5.     std::string message;
  6.  
  7. public:
  8.     CustomException( std::string message );
  9.     inline std::string getMessage() { return message; };
  10.  
  11. };


Aquí hemos declarado una clase simple, CustomException. La clase tiene un miembro de datos, mensaje , Que celebrará el mensaje de error asociado con nuestra excepción. Definimos un constructor de base que toma una cadena como un argumento para que el mensaje, y tenemos un acceso para mensaje . Ahora, podemos echar una instancia de nuestra clase CustomException como una excepción, como esta:

CPP Código: [ Select ]
void doSomething() {
   
    throw CustomException( "An error occurred." );
}
  1. void doSomething() {
  2.    
  3.     throw CustomException( "An error occurred." );
  4. }


Al principio, esto no parece más útil que el lanzamiento de una cadena en solitario. Heck, incluso nos obliga a escribir más código sólo para crear la clase! Pero mire el concepto de nuevo. Ahora que nuestra excepción se representa como un objeto completo de nuestra clase en lugar de una primitiva o una cadena, podemos añadir montones y montones de información a nuestros excepción añadiendo más datos a los miembros de nuestra clase. Por ejemplo, permite añadir unas cuantas piezas más de la información a nuestra clase:

Código: [ Select ]
class CustomException {
 
private:
   
    std::string message;
    int errorCode;
    bool fatal;

 
public:
    CustomException( std::string message );
    inline std::string getMessage() { return message; };
    inline int getErrorCode() { return errorCode; };
    inline bool isFatal() { return fatal; };

 
};
  1. class CustomException {
  2.  
  3. private:
  4.    
  5.     std::string message;
  6.     int errorCode;
  7.     bool fatal;
  8.  
  9. public:
  10.     CustomException( std::string message );
  11.     inline std::string getMessage() { return message; };
  12.     inline int getErrorCode() { return errorCode; };
  13.     inline bool isFatal() { return fatal; };
  14.  
  15. };


Ahora que el weve añadido datos adicionales sobre las condiciones y circunstancias que rodean el problema que generó la excepción, sea cual sea la función termina el manejo de la función estará en mejores condiciones para hacer frente correctamente.

El enfoque de diseño común para las clases de excepción es definir una clase de excepción base que contiene información muy básica acerca de una clase. A continuación, crearía subclases para diferentes tipos de excepciones, con cada subclase que contiene información específica relativa a cada una excepción particular.

Por ejemplo, decir que quería crear un nuevo tipo de excepción, FileNotFoundException, para tratar con el archivo de E / S. Simplemente podemos extender nuestra clase CustomException y agregar la información pertinente:

Código: [ Select ]
class FileNotFoundException : public CustomException {
 
private:
   
    std::string filename;
 
public:
    FileNotFoundException( std::string filename );
    inline std::string getFilename() { return filename; };

   
    // Override the getMessage() method
    inline std::string getMessage() {
        std::stringstream ss;
        ss << "File not found: " << filename;
        return ss.str();
    }

   
    // note: all other member data and methods are inherited!
};
  1. class FileNotFoundException : public CustomException {
  2.  
  3. private:
  4.    
  5.     std::string filename;
  6.  
  7. public:
  8.     FileNotFoundException( std::string filename );
  9.     inline std::string getFilename() { return filename; };
  10.    
  11.     // Override the getMessage() method
  12.     inline std::string getMessage() {
  13.         std::stringstream ss;
  14.         ss << "File not found: " << filename;
  15.         return ss.str();
  16.     }
  17.    
  18.     // note: all other member data and methods are inherited!
  19. };


Ahora, podemos lanzar una FileNotFoundException si nos encontramos en una situación donde no podemos abrir un archivo para lectura o escritura. En lugar de la inicialización de la excepción con un mensaje, y pasarle el nombre de archivo que no se podía abrir, y cada vez que llamamos getMessage () , Nuestra versión reemplaza imprimirá "Archivo no encontrado:" y el nombre del archivo. Neat!


Uso de bloques try / catch para controlar excepciones


Ahora que lanzar excepciones eran cómodas, le permite echar un vistazo a cómo capturar y manejar una excepción que ha sido lanzado.

En C + +, usamos un intentar bloque para rodear el código que tiene la posibilidad de excepciones. Código de intentar bloques completamente la función normal en circunstancias no excepcionales.

Código: [ Select ]
try {
    std::cout << "Calling a function that may throw an exception..."
        << std::endl;
    doSomething();  // may throw an exception
}
  1. try {
  2.     std::cout << "Calling a function that may throw an exception..."
  3.         << std::endl;
  4.     doSomething();  // may throw an exception
  5. }


Sin embargo, una vez que se produce una excepción por una llamada a una función dentro del bloque, la ejecución se detiene en esa línea dentro del bloque y se entrega a intentar s socios, la coger bloque. Permite añadir un coger bloque que las capturas CustomException objetos que pueden haber sido arrojadas por doSomething () :

Código: [ Select ]
try {
    std::cout << "Calling a function that may throw an exception..."
        << std::endl;
    doSomething();  // may throw an exception
}
catch( CustomException e ) {
   
    std::cout << "Exception: " << e.getMessage();
}

  1. try {
  2.     std::cout << "Calling a function that may throw an exception..."
  3.         << std::endl;
  4.     doSomething();  // may throw an exception
  5. }
  6. catch( CustomException e ) {
  7.    
  8.     std::cout << "Exception: " << e.getMessage();
  9. }


Observe cómo la excepción se transfiere al bloque catch y se puede acceder a través de la variable CustomException E . (Yo elegí a nombre de la variable de E , Pero usted puede elegir cualquier nombre legal que usted desee, al igual que con la función argumentos). Ahora podemos acceder a toda la información necesaria contenida en la excepción, y ejecutar código de forma apropiada sobre la base de esa información.

Por la captura de valor frente a la captura por referencia


Ahora, este código se compilará y el trabajo, pero los theres un problema. Cada vez que capturar las excepciones en el camino se ha visto, estamos la captura por valor de . Este concepto tiene una relación directa con el paso de argumentos a las funciones por valor. La captura de la excepción por valor significa que cada vez que la excepción se pasa a la pila de llamadas, una copia de la excepción se hace y se envía a la siguiente función. Esto lleva a una reducción en la eficiencia (grandes, complejos excepciones, las clases pueden ser muy complejos y tienen más tiempo para copia) y un desperdicio de recursos (memoria).

Entonces, ¿cuál es la solución? Como puede haber adivinado, se puede detectar la excepción por referencia en vez de por valor. El cambio en la sintaxis debería ser muy familiar a cualquiera que se utiliza para pasar argumentos de la función por referencia:

Código: [ Select ]
try {
    std::cout << "Calling a function that may throw an exception..."
        << std::endl;
    doSomething();  // may throw an exception
}
catch( CustomException& e ) {
   
    std::cout << "Exception: " << e.getMessage();
}
  1. try {
  2.     std::cout << "Calling a function that may throw an exception..."
  3.         << std::endl;
  4.     doSomething();  // may throw an exception
  5. }
  6. catch( CustomException& e ) {
  7.    
  8.     std::cout << "Exception: " << e.getMessage();
  9. }


Observe el cambio: E se declara como una referencia a un CustomException en lugar de una variable CustomException regular.

Aparte de rendimiento y gestión de los recursos, la razón principal para capturar las excepciones en función es evitar la datos de corte de . Datos de corte se produce cuando un objeto de una determinada clase se copia en un objeto de uno de sus superclases. Cuando esto sucede, los datos y el comportamiento específico de la subclase se "cortado" en cualquier únicamente los datos de la superclase se conserva.

CPP Código: [ Select ]
try {
   
    // Assume that FileNotFoundException is a subclass
    // of CustomException
    throw FileNotFoundException( "example.txt" );
   
}
catch( CustomException e ) {
   
    std::cout << "Exception: " << e.getMessage();
}
  1. try {
  2.    
  3.     // Assume that FileNotFoundException is a subclass
  4.     // of CustomException
  5.     throw FileNotFoundException( "example.txt" );
  6.    
  7. }
  8. catch( CustomException e ) {
  9.    
  10.     std::cout << "Exception: " << e.getMessage();
  11. }


Considere el código anterior. ¿Cuál sería el resultado generado por el bloque catch en este caso? Lo ideal sería que imprimir "Archivo no encontrado:", seguido por el nombre de archivo, como se especifica en FileNotFoundException.getMessage (). Pero este no es el caso! El problema es que todos los datos específicos de FileNotFoundException, como el miembro de datos de nombre de archivo, habrá una merma de modo que el objeto se ajusta a E, A CustomException.

Para evitar esto, cogemos la excepción de referencia, que se asegurará de que toda la información original se conserva en la excepción. A continuación, puede lanzar la referencia a una referencia FileNotFoundException, y el acceso a todos los miembros apropiados, incluyendo la versión correcta de getMessage ().


Captura...


Ya sabemos que podemos especificar muchas diferentes coger bloques para controlar las excepciones de diversos tipos. Pero ¿y si se establece una excepción que no estamos dispuestos a coger? Esto puede causar todo tipo de comportamiento indebido en nuestros programas. Idealmente, se casó, como para asegurar que cubrimos todas las bases , Incluidas las excepciones que no puede haber sido aceptar. Para ello, utilizamos una sintaxis especial para atrapar cualquier resto de excepciones para el que el actual coger bloque no se ha especificado: el "..." Símbolo.

Código: [ Select ]
try{
    doSomething();
}
catch( CustomException& ce ) {
    std::cout << "Exception: " << ce.getMessage();
}
catch( ... ) {
    std::cout << "An unknown exception was caught!";
}

  1. try{
  2.     doSomething();
  3. }
  4. catch( CustomException& ce ) {
  5.     std::cout << "Exception: " << ce.getMessage();
  6. }
  7. catch( ... ) {
  8.     std::cout << "An unknown exception was caught!";
  9. }


La sintaxis es muy simple. En lugar de especificar el tipo de excepción a la captura, nos elipses uso simple (...) Para indicar que este bloque de capturas que captura todo lo lanzado que no se trató de cualquier bloque de captura anterior. Por esta razón, casi siempre nos ponen las capturas (...), Bloque al final de todos los demás, para asegurar que todas las excepciones se tienen en cuenta.

Tenga en cuenta que no tenemos forma de acceder a la excepción de que es capturado por este bloque. No hay manera de obtener su valor (s) o de manipularla.


Cómo volver a lanzar una excepción


Hay muchas veces cuando una función se puede capturar una excepción, pero es incapaz de abordar de manera adecuada. En este caso, por lo general quieren pasar la excepción de la pila de llamadas a la más alta función al lado de tratar con él. Pasamos en esta excepción, o volver a lanzar la excepción, utilizando el volver a lanzar Palabra clave:

Código: [ Select ]
try{
    doSomething();
}
catch( CustomException& ce ) {
    std::cout << "Exception: " << ce.getMessage();
    rethrow ce;
}
catch( ... ) {
    std::cout << "An unknown exception was caught!";
    rethrow;
}
  1. try{
  2.     doSomething();
  3. }
  4. catch( CustomException& ce ) {
  5.     std::cout << "Exception: " << ce.getMessage();
  6.     rethrow ce;
  7. }
  8. catch( ... ) {
  9.     std::cout << "An unknown exception was caught!";
  10.     rethrow;
  11. }


La sintaxis para volver a lanzar es muy simple. En el caso en el que se captura una excepción de un tipo conocido, simplemente volver a lanzar el objeto que fue atrapado, indicado por la variable utilizada por el bloque catch. Del mismo modo, en el caso de una excepción de un tipo desconocido es capturado con (...), Simplemente decir volver a lanzar . Esto debe tener sentido ya que no tienen acceso directo al objeto en este caso. Pero no se preocupe, el compilador sabe mejor, y la excepción se vuelve a iniciar correctamente.


Hacer promesas (y de mantenimiento de ellos!)



Que he mencionado antes en este tutorial que la tirar palabra clave tiene dos usos. Weve visto uno de ellos: para lanzar una excepción dentro de una función. Ahora vamos a echar un vistazo a la utilización de otros.

Cuando usamos el tirar palabra clave en la cabecera de una función, indica qué tipo de excepciones que la función puede lanzar. Por lo tanto, cualquier tipo que no aparece en el tiro () parte de la cabecera no puede y no será lanzada por esa función. Esto se llama una garantía . En esencia, está haciendo una promesa a todos los que usan la función de que existe una lista fija de tipos de excepciones que puede lanzar su función, y que estos son los únicos que deben ser vistos en tratar de bloques con su función.

Permite revisar nuestra función simple, doSomething () , Para incluir esta información:

Código: [ Select ]
void doSomething(int value) throw( int, CustomException ) {
   
    if( value > 5 ) {
        throw CustomException( "An error occurred." );
    }
    else {
        throw 18;
    }
}
  1. void doSomething(int value) throw( int, CustomException ) {
  2.    
  3.     if( value > 5 ) {
  4.         throw CustomException( "An error occurred." );
  5.     }
  6.     else {
  7.         throw 18;
  8.     }
  9. }


Aquí vemos que el doSomething () se declara ser capaz de lanzar dos tipos de excepciones: los números enteros y CustomExceptions. Otras funciones que se llaman ahora esta función sólo tiene que escribir los bloques catch para estos dos tipos de datos, y nada más. doSomething () es la promesa de que si se produce una excepción, siempre será de uno de esos dos tipos.

Nota: una función puede lanzar una excepción de cualquier tipo que figuran en el tiro () la cláusula de la cabecera de la función, y cualquier subclase de esos tipos.

Ahora veamos la tres niveles de garantías de excepción, o la seguridad de excepción, que una función puede tener:

La debilidad de Garantía
Si la función se produce una excepción, no hay recursos se fuga como resultado.

Sólida garantía de
Si la función se produce una excepción, no hay recursos se filtró y los programas estatales no difiere de lo que era antes de la operación.


La función de las garantías que no habrá excepciones que se desprendan, y que la operación siempre tendrán éxito en todas las circunstancias.

Por supuesto, Mi gusto de poder que no tiene garantías de tiro para todas nuestras funciones, pero en realidad esto no es sólo posible en la mayoría de los sistemas. Aunque es la mejor garantía para tener, a menudo es muy difícil de lograr.

Permite revisar nuestra función simple, doSomething () , Una última vez para darle un tiro si no se garantiza:

Código: [ Select ]
void doSomething(int value) throw() {
   
    value = 0;
}
  1. void doSomething(int value) throw() {
  2.    
  3.     value = 0;
  4. }


Tenga en cuenta que para garantizar un lanzamiento sin garantía, se utiliza un vacío throw () cláusula para indicar que esta función no puede y no va a arrojar ningún tipo de excepción.


Excepciones STL


El [sigla = Biblioteca de plantillas estándar: 3618k50i] STL [/acronym] contiene una clase de excepción, std:: Excepción , Que sirve como la clase base para todas las excepciones lanzadas por las clases de STL y funciones. Similar a la nuestra getMessage () método en nuestra clase CustomException propia, la clase de excepción STL contiene un método denominado lo que () que pueden ser utilizados para obtener el mensaje de error asociado con la excepción. Al utilizar las clases de STL, su a menudo una buena idea para detectar esta excepción en el caso de que algo va mal:

Código: [ Select ]
try {
    std::cout << "cout is a std::ostream object and could throw an exception";
}
catch( std::exception& ex ) {
    std::cerr << "Exception: " << ex.what();
}

  1. try {
  2.     std::cout << "cout is a std::ostream object and could throw an exception";
  3. }
  4. catch( std::exception& ex ) {
  5.     std::cerr << "Exception: " << ex.what();
  6. }


Además, podemos modificar nuestra clase CustomException propio para ampliar la clase de excepción STL, y así utilizar el mismo bloque catch para capturar todas las excepciones derivadas de nuestra también. Ill dejar que el ejercicio de usted como jugar con tus nuevos conocimientos de las excepciones.


Conclusión


Ahora debe tener una comprensión sólida de cómo implementar y utilizar las excepciones en C + +. Usted debe entender los conceptos de lanzar, atrapar, y cómo volver a lanzar las excepciones, así como las garantías diferentes funciones que puede hacer acerca de las excepciones.

Yo siempre bienvenidos preguntas o comentarios acerca de este tutorial. Basta con enviar una respuesta o PM me im glad to help!
Attachments:
Exceptions.zip

(1.73 KiB) 778 veces

Complete source code for various examples using exceptions, including the CustomException class.

The Beer Monocle. Classy.
  • Anonymous
  • Bot
  • No Avatar
  • Registrado: 25 Feb 2008
  • Mensajes: ?
  • Loc: Ozzuland
  • Status: Online

Nota Marzo 19th, 2008, 10:52 pm

Publicar Información

  • Total de mensajes en este tema: 1 mensaje
  • Moderador: Tutorial Writers
  • Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 3 invitados
  • No puede abrir nuevos temas en este Foro
  • No puede responder a temas en este Foro
  • No puede editar sus mensajes en este Foro
  • No puede borrar sus mensajes en este Foro
  • No puede enviar adjuntos en este Foro
 
 

© 2011 Unmelted, LLC. Ozzu® es una marca registrada de Unmelted, LLC