Skip to content

Latest commit

 

History

History
103 lines (87 loc) · 3.47 KB

File metadata and controls

103 lines (87 loc) · 3.47 KB

Exceptions

  • C’est un mécanisme pour gérer proprement les erreurs à l’exécution.

  • Quand une fonction rencontre une erreur :

    • elle “lance” une exception
    • la fonction courante est terminée immédiatement
    • les fonctions appelantes sont aussi terminées jusqu’à trouver un morceau de code qui sache gérer l’exception
    • si aucun bloc de code ne traite l’exception, le programme se termine.
  • Les erreurs "classiques" à traiter avec des exceptions sont :

    • dépassement d’indices dans les tableaux
    • dépassement de capacité (le résultat d’un calcul est plus grand que le maximum représentable par la variable : ex stocker un nombre plus grand que 255 dans un char)
    • division par zéro
    • allocation mémoire impossible (manque de mémoire).
  • Le mécanisme des exceptions se gère avec 3 mots clés

    • try : signale une portion de code pouvant générer un erreur
    • throw : lance une erreur
    • catch : traite l’erreur
int division(int a,int b) // Calcule a divisé par b. 
{
    if(b==0){
        throw string("ERREUR : Division par zéro !"); //lance l’exception
    } 
    else return a/b;
} //sinon calcule la division

int main() {
    int a=10,b=0;
    try {
        cout << a << " / "<< b << " = " << division(a,b) << endl;
    } 
    catch(string const& chaine){
        cerr << chaine << endl;  //on utilise le flux standard d’erreur
    } 
    return 0;
}
  • Chaque bloc try doit être suivi d'un bloc catch

  • Chaque bloc catch doit être précédé d’un bloc try ou d’un bloc catch

  • Le code écrit derrière l’instruction throw n’est pas exécuté. Le code reprend après le bloc catch

  • L’instruction throw doit toujours se trouver dans un bloc try

  • On attrape les exceptions par référence constante (const&) et pas par valeur. Cela permet d'éviter une copie et de conserver le polymorphisme de l'objet reçu

  • On peut lancer n’importe quel objet comme exception (entier, chaîne de caractère, …)

  • Il faut préciser dans le paramètre du catch quel type on attrape

catch(int e) { …} // On rattrape les entiers lancés 
catch(string const& e){} // On rattrape les strings lancés. 
catch(Animal const& e) {} // On rattrape les animaux. 
  • Pour attraper n’importe quel type d’exception on utilise …
catch(…){//on ne peut pas utilise l’objet puisque non passé en paramètre }
  • On peut aussi attraper toutes les exceptions qui dérivent de la classe standard exception
catch(exception const& e){
    cerr << e.what;
    } //on peut utiliser e
  • Il est possible de créer ses propres classes d’exception en dérivant la classe exception. Cela permet de préciser plusieurs éléments sur l’exception
# include <exception>
struct DivisionParZeroException : public std::exception
{
    DivisionParZeroException (const std::string & message = "a essaye de diviser par zero "):m_message ( message ) {}
    virtual ~ DivisionParZeroException () throw () {}
    virtual const char * what () const throw () {
        return m_message . c_str ();
    }
    private :
        std :: string m_message ;
};

double quotient ( const int numerateur , const int denominateur )
{
    if(denominateur ==0)
        throw DivisionParZeroException();
    // ...
}

// dans la fonction appelante ( main par exemple ) :
try
{
    double div = quotient (3, 0);
}
catch (DivisionParZeroException & e)
{
    cout << " Erreur : " << e. what() << endl;
}

Exercice 16