Rechercher
 

Améliorations / Corrections

Vous avez des améliorations (ou des corrections) à proposer pour ce document : je vous remerçie par avance de m'en faire part, cela m'aide à améliorer le site.

Emplacement :

Description des améliorations :

Instruction try / catch

Syntaxe d'utilisation

try {
    [statement]...
} catch( ... ) {
    [statement]...
}
try {
    [statement]...
} catch( const exceptiontype & exception ) {
    [statement]...
}

Une exception correspond (comme son nom l'indique) à un état exceptionnel observé dans le système : la plupart du temps, cela correspond à un état d'erreur. L'instruction try permet de surveiller un bloc d'instructions et, au cas ou une exception serait déclenchée, de fournir un (ou plusieurs) gestionnaire(s) d'erreur(s) via le mot clé catch. Cette instruction, d'une certaine manière, fonctionne un peu comme l'instruction if / else, dans le sens ou le mot clé catch (tout comme le mot clé else) est obligatoirement associé à un try.

Deux fichiers d'entêtes sont intimement liés à cette instruction : l'entête <exception> et l'entête <stdexcept>. Dans les deux cas, des classes d'exceptions (donc d'erreur) y sont définis. Parmi ces classes, la classe exception : normalement, toute classe d'exception devrait dériver de cette dernière.

Notez qu'il existe une syntaxe particulière pour un bloc catch qui permet d'indiquer qu'il permettra de traiter n'importe quel type d'erreurs : catch( ... ) { }. Si cette syntaxe est utilisée, que l'exception dérive de la classe exception ou non, qu'elle soit de type objet ou non (en C++ une exception peut être de n'importe quel type : int, double, string, ...), elle pourra être traitée par ce bloc.

Il est donc possible de définir plusieurs blocs catch. Dans ce cas, il est important de correctement les ordonner. Effectivement, le programme cherchera à exécuter le premier bloc qui correspondra en regardant du premier au dernier. Dès l'un des blocs pourra être retenu, il sera exécuté. En conséquence, si deux types d'exception testées ont un lien d'héritage, alors le type le plus spécifique devra être placé avant le type plus générique. De même si la syntaxe catch( ... ) { } est utilisée, alors ce bloc catch devra être le dernier. Si ces règles ne sont pas respectées, ce n'est pas grave : une erreur de compilation sera produite et vous serez donc bien obligé de retravailler votre code.

Exemple de code

#include <cstdlib>
#include <ctime>

#include <iostream>
#include <stdexcept>

using namespace std;

/* Imagine a library that can throw an exception. */
double fct() {
    int value = rand() % 3;
    if ( value == 0 ) throw domain_error( "0 is a Bad value" );
    return 1.0 / value;
}

/* Here an usage of this library */
int main() {

    srand( time( NULL ) );

    try {
        cout << "Result == " << fct() << endl;
    } catch( const exception & e ) {
        cerr << e.what() << endl;
    } catch( ... ) {
        cerr << "Another unknown error" << endl;
    }
    
    return 0;
}

Sujets connexes