next up previous contents
Next: Correspondance des arguments Up: Exceptions Previous: Généralités

Exceptions en C++

En C++, on lancera (throw) un exception par une throw-expression. Une partie de programme sera associée à un traite-exception par un try-bloc, à la fin du try-bloc, un traite-exception (introduit par le mot clé catch) définira le comportement en cas d'exception lancée dans le bloc :

class erreur{
//...
public:
  erreur(const char *p){
    //...
  };
};
double racine(double d){
  if(d<0)catch "arg. negatif";
  return(sqrt(d));
}
void essai(double d){
  double r;
  try{
    r=racine(d);
    // ...
  }
  catch(const char *p){
    cerr<<p<<endl;
    throw erreur(p);
  }
}

Dans le cas d'un appel de essai avec un argument négatif, une exception sera levée dans racine, qui sera traitée dans essai, et qui lèvera elle-même une exception de type erreur.

Décrivons de façon plus précise le mécanisme. Une exception a un type, quand une exception est lancée, un objet temporaire statique du type de l'exception est créé et initialisé.

Le contrôle sera transféré jusqu'au traite-exception, le plus proche, qui peut correspondre à l'expression de l'exception lancée. Le traite-exception le plus proche est celui correspondant au ``try-bloc'' dans lequel le contrôle est entré le plus récemment.

La correspondance, pour l'expression associée à l'exception, est définie de façon similaire à la correspondance des paramètres pour les fonctions. Une fois ce traite-exception atteint, tout se passe comme pour le passage des paramètres. Le contrôle reprendra après son cours normal. Si aucun traite-exception approprié n'existe, après le parcours complet du contrôle du programme, une fonction spéciale terminate sera appelée, qui termine l'exécution.

Pour se ``brancher'' sur le traite-exception correspondant à l'exception, on va parcourir la pile d'exécution, et, bien entendu, ce traite-exception sera évalué dans un autre contexte que le contexte où a été lancé l'exception (ce qui exclut de faire référence à des objets locaux). De plus, il faut aussi que ce ``dépilage'' se fasse correctement, en particulier tous les objets seront détruits et il y aura donc des appels aux destructeurs.

On peut aussi retransmettre l'exception à un autre traite-exception dans un traite-exception, c'est ce que fait le throw sans argument :

void essai(double d){
  double r;
  try{
    r=racine(d);
    // ...
  }
  catch(const char *p){
    cerr<<p<<endl;
    // traiter ce cas ...
  }
  catch( ... ){ // n'importe quelle exception
     //...
     throw;     // transmettre
  }
}
Ceci peut être indispensable, car il peut se faire qu'une exception arrive dans un traite exception, sans que le type auquel son expression est associée, ne soit connu par le traite-exception, dans ce cas, on peut juste ``capter'' cette exception et la retransmettre.




next up previous contents
Next: Correspondance des arguments Up: Exceptions Previous: Généralités


Mon Oct 20 14:02:48 MET 1997