'>

les Exceptions au C++

Exceptions fournissent un moyen de réagir à des circonstances exceptionnelles (comme des erreurs d'exécution) dans notre programme par le transfert du contrôle aux fonctions spéciales appelées gestionnaires.

Pour attraper les exceptions il faut placer une portion de code en cours d'inspection d'exception. Ceci est fait en plaçant la partie de code dans un bloc try. Quand une circonstance exceptionnelle se pose au sein de ce bloc, une exception est levée qui transfère le contrôle au gestionnaire d'exception. Si aucune exception n'est levée, le code se poursuit normalement et tous les gestionnaires sont ignorés.

Une exception est levée en utilisant le mot clé throw à l'intérieur du bloc try. Les gestionnaires d'exception sont déclarées avec la capture de mot-clé, qui doit être placé immédiatement après le bloc try:


 // exceptions #include <iostream> using namespace std; int main () { try { throw 20; } catch ( int e) { cout << "An exception occurred. Exception Nr. " << e << endl; } return 0; }

   

  Une exception s'est produite.  Exception Nr.  20



Le code sous la gestion des exceptions est enfermé dans un bloc try. Dans cet exemple, ce code génère simplement une exception:



   

 throw 20;



Une expression lancer accepte un paramètre (dans ce cas la valeur entière 20), qui est passé comme un argument pour le gestionnaire d'exception.

Le gestionnaire d'exception est déclaré avec le mot clé catch. Comme vous pouvez le voir, il suit immédiatement l'accolade de fermeture du bloc try. Le format de capture est semblable à une fonction régulière qui a toujours au moins un paramètre. Le type de ce paramètre est très important, car le type de l'argument passé par l'expression jet est vérifié contre elle, et seulement dans le cas où ils correspondent, l'exception est interceptée.

Nous pouvons chaîne plusieurs gestionnaires (prises expressions), chacun avec un type de paramètre différent. Seul le gestionnaire qui correspond à son type avec l'argument spécifié dans l'instruction throw est exécutée.

Si nous utilisons une ellipse (...) en tant que paramètre de la capture, ce gestionnaire va attraper une exception quel que soit le type de l'exception jet est. Ceci peut être utilisé comme un gestionnaire par défaut qui intercepte toutes les exceptions non capturées par d'autres gestionnaires s'il est précisé à la fin:


   

 try { // code here } catch ( int param) { cout << "int exception" ; } catch ( char param) { cout << "char exception" ; } catch (...) { cout << "default exception" ; }



Dans ce cas, le dernier gestionnaire serait attraper aucune exception jeté avec n'importe quel paramètre qui n'est ni un int, ni un chevalier.

Après une exception a été traitée à l'exécution du programme reprend après le bloc try-catch, pas après l'instruction throw!.

Il est également possible d'imbriquer des blocs try-catch dans les blocs try plus externes. Dans ces cas, nous avons la possibilité qu'un bloc catch interne avant l'exception de son niveau externe. Cela se fait avec l'expression jet, sans arguments. Par exemple:

   

 try { try { // code here } catch ( int n) { throw ; } } catch (...) { cout << "Exception occurred" ; }



spécifications d'exception

Lors de la déclaration d'une fonction, nous pouvons limiter le type d'exception, il pourrait jeter directement ou indirectement, en ajoutant un suffixe lancer à la déclaration de la fonction:



   

 float myfunction ( char param) throw ( int );



Ceci déclare une fonction appelée myfunction qui prend un argument de type char et renvoie un élément de type float. La seule exception que cette fonction pourrait jeter une exception de type int. Si elle lève une exception avec un type différent, que ce soit directement ou indirectement, il ne peut pas être capturé par un gestionnaire régulier de type int.

Si ce spécificateur est laissé vide avec aucun type, cela signifie que la fonction n'est pas autorisé à lever des exceptions. Fonctions sans spécificateur (fonctions régulières) sont autorisés à lever des exceptions avec tout type:

 1
 2


   

 int myfunction ( int param) throw (); // no exceptions allowed int myfunction ( int param); // all exceptions allowed



Exceptions standard
La bibliothèque C + + standard fournit une classe de base spécialement conçu pour déclarer la projection d'objets comme des exceptions. Il est appelé exception et est défini dans le fichier d'en-tête de <exception> sous le namespace std. Cette classe possède le défaut d'habitude et constructeurs de copie, les opérateurs et destructeurs, plus une fonction de membre virtuel supplémentaire appelé ce qui retourne une séquence de caractères terminée par NULL (char *) et qui peut être écrasée dans les classes dérivées pour contenir une sorte de description de l' exception.


 // standard exceptions #include <iostream> #include <exception> using namespace std; class myexception: public exception { virtual const char * what() const throw () { return "My exception happened" ; } } myex; int main () { try { throw myex; } catch (exception& e) { cout << e.what() << endl; } return 0; }

   

  Mon exception a eu lieu.



Nous avons placé un gestionnaire qui intercepte les objets d'exception par référence (remarquez l'esperluette & après le type), donc cette capture également les classes dérivées à partir exception, comme notre objet myex de MyException de classe.

Toutes les exceptions levées par les composants de la bibliothèque C + + standard lèvent des exceptions découlant de cette std :: classe d'exception. Ce sont:

exception     Description
bad_alloc     lancée par neuf en cas d'échec d'allocation
bad_cast     lancée par dynamic_cast quand échoue avec un type référencé
bad_exception     jeté quand un type d'exception ne correspond à aucune prise
bad_typeid     lancée par typeid
ios_base :: échec     lancée par fonctions dans la bibliothèque iostream

Par exemple, si nous utilisons l'opérateur new et la mémoire ne peut être attribuée, une exception de type bad_alloc est jeté:

 try { int * myarray= new int [1000]; } catch (bad_alloc&) { cout << "Error allocating memory." << endl; }



Il est recommandé d'inclure toutes les allocations de mémoire dynamique à l'intérieur d'un bloc try qui attire ce type d'exception pour effectuer une action propre à la place d'une terminaison anormale du programme, qui est ce qui arrive quand ce type d'exception est levée et non capturé. Si vous voulez forcer une exception bad_alloc de le voir en action, vous pouvez essayer d'allouer une vaste gamme; Sur mon système, en essayant d'allouer 1 milliard int s jeté une exception bad_alloc.

Parce bad_alloc est dérivée de la norme exception de la classe de base, nous pouvons prendre en charge cette même exception en attrapant les références à la classe d'exception:

   

 // bad_alloc standard exception #include <iostream> #include <exception> using namespace std; int main () { try { int * myarray= new int [1000]; } catch (exception& e) { cout << "Standard exception: " << e.what() << endl; } return 0; }

  
Publié par Drupal Study