Gestion des exceptions en C ++

Gestion des exceptions en C ++
Il existe trois types d'erreurs logicielles qui existent. Ce sont des erreurs de syntaxe, des erreurs de logique et des erreurs d'exécution.

Erreurs de syntaxe

Une expression, une instruction ou une construction à tort est typique est une erreur de syntaxe.

Considérez les deux déclarations suivantes:

int arr [] = 1, 2, 3; //correct
int arr = 1, 2, 3; // Erreur de syntaxe, manquant []

Ce sont des définitions du même tableau. Le premier est correct. Le second manque [], et c'est une erreur de syntaxe. Un programme avec une erreur de syntaxe ne réussit pas à compiler. La compilation échoue avec un message d'erreur indiquant l'erreur de syntaxe. Une bonne chose est qu'une erreur de syntaxe peut toujours être corrigée si le programmeur sait ce qu'il fait.

Erreur logique

Une erreur logique est une erreur commise par le programmeur lorsque un mauvais codage logique est fait. Cela peut être le résultat de l'ignorance du programmeur aux caractéristiques du langage de programmation ou un malentendu de ce que le programme devrait faire.

Dans cette situation, le programme est compilé avec succès. Le programme fonctionne bien, mais il produit de mauvais résultats. Une telle erreur peut être due à la réalisation d'une boucle 5 fois lorsqu'elle est faite pour itérer 10 fois. Il se peut également qu'une boucle soit inconsciemment faite pour itérer l'infini. La seule façon de résoudre ce type d'erreur est de faire une programmation minutieuse et de tester soigneusement le programme avant de le remettre au client.

Erreurs d'exécution

Les entrées erronées ou exceptionnelles provoquent des erreurs d'exécution. Dans ce cas, le programme a été compilé avec succès et fonctionne bien dans de nombreuses situations. Dans certaines situations, le programme se bloque (et s'arrête).

Imaginez que dans un segment de code de programme, 8 doit être divisé par un certain nombre de dénominateurs. Donc, si le numérateur 8 est divisé par le dénominateur 4, la réponse (quotient) serait 2. Cependant, si l'utilisateur saisit 0 comme dénominateur, le programme se bloquerait. La division par 0 n'est pas autorisée en mathématiques, et elle n'est pas non plus autorisée à calculer. Division par zéro doit être évité dans la programmation. La gestion des exceptions gère les erreurs d'exécution, comme la division par zéro. Le programme suivant montre comment gérer le problème de division par zéro sans utiliser la fonction d'exception en C ++:

#inclure
Utilisation de Namespace Std;
int main()

int numérateur = 8;
int dénominateur = 2;
si (dénominateur != 0)

INT Result = Numerator / Denominator;
couter << result << '\n';

autre

couter << "Division by zero is not permitted!" << '\n';

retour 0;

La sortie est 4. Si le dénominateur était de 0, la sortie aurait été:

«La division par zéro n'est pas autorisée!"

Le code principal ici est une construction if-else. Si le dénominateur n'est pas 0, la division aura lieu; S'il est 0, la division n'aura pas lieu. Un message d'erreur sera envoyé à l'utilisateur et le programme continue de s'exécuter sans s'écraser. Les erreurs d'exécution sont généralement gérées en évitant l'exécution d'un segment de code et en envoyant un message d'erreur à l'utilisateur.

La fonction d'exception en C ++ utilise un bloc d'essai pour le bloc IF et un bloc de capture pour le bloc Else pour gérer l'erreur, comme suit:

#inclure
Utilisation de Namespace Std;
int main()

int numérateur = 8;
int dénominateur = 2;
essayer

si (dénominateur != 0)

INT Result = Numerator / Denominator;
couter << result << '\n';

autre

lancer 0;


Catch (int err)

if (err == 0)
couter << "Division by zero is not permitted!" << '\n';

retour 0;

Notez que l'en-tête d'essai n'a pas d'argument. Notez également que le bloc couvert, qui est comme une définition de fonction, a un paramètre. Le type de paramètre doit être le même que l'opérande (argument) de l'expression de lancer. L'expression de lancer est dans le bloc d'essais. Il lance un argument du choix du programme. De cette façon, le code dans le bloc d'essai n'est pas exécuté. Ensuite, le bloc couvert affiche le message d'erreur.

Cet article explique la gestion des exceptions en C++. Les connaissances de base en C ++ sont une condition préalable pour le lecteur pour comprendre cet article.

Contenu de l'article:

  • Fonction lançant une exception
  • Plus d'un bloc de capture pour un bloc d'essai
  • Blocs d'essai / catch imbriqués
  • NO EXCEPTER SPECICICATEUR
  • La fonction spéciale std :: terminée ()
  • Conclusion

Fonction lançant une exception:

Une fonction peut également lancer une exception comme ce que fait le bloc d'essai. Le lancer se déroule dans la définition de la fonction. Le programme suivant illustre ceci:

#inclure
Utilisation de Namespace Std;
void fn (const char * str)

if (islower (str [0]))
jeter «l»;

int main()

essayer

fn ("Smith");

Catch (char ch)

if (ch == 'l')
couter << "Person's name cannot begin in lowercase!" << '\n';

retour 0;

Notez que cette fois, le bloc d'essai a juste l'appel de fonction. C'est la fonction appelée qui a l'opération de lancer. Le bloc de capture attrape l'exception et la sortie est:

«Le nom de la personne ne peut pas commencer en minuscules!"

Cette fois, le type lancé et capturé est un char.

Plus d'un bloc de capture pour un bloc d'essai:

Il peut y avoir plus d'un bloc de fourreau pour un bloc d'essai. Imaginez la situation où une entrée peut être l'un des caractères du clavier, mais pas un chiffre et non un alphabet. Dans ce cas, il doit y avoir deux blocs de capture: un pour un entier pour vérifier le chiffre et un pour un char pour vérifier l'alphabet. Le code suivant illustre ceci:

#inclure
Utilisation de Namespace Std;
char char = '*';
int main()

essayer

if (isdigit (entrée))
lancer 10;
if (isalpha (entrée))
jeter «z»;

Catch (int)

couter << "Digit input is forbidden!" << '\n';

attraper (char)

couter << "Character input is forbidden!" << '\n';

retour 0;

Il n'y a pas de sortie. Si la valeur de l'entrée était un chiffre, E.g., «1», la sortie aurait été:

"L'entrée de chiffres est interdite!"

Si la valeur de l'entrée était un alphabet, e.g., «A», la sortie aurait été:

"L'entrée des caractères est interdite!"

Notez que dans la liste des paramètres des deux blocs de capture, il n'y a pas de nom d'identifiant. Notez également que dans la définition des deux blocs de fourreaux, les arguments particuliers lancés n'ont pas été vérifiés si leurs valeurs sont exactes ou non.

Ce qui compte pour une prise, c'est le type; Une prise doit correspondre au type d'opérande lancé. La valeur particulière de l'argument (opérande) lancé peut être utilisé pour une vérification supplémentaire si nécessaire.

Plus d'un gestionnaire pour le même type

Il est possible d'avoir deux gestionnaires du même type. Lorsqu'une exception est lancée, le contrôle est transféré au gestionnaire le plus proche avec un type de correspondance. Le programme suivant illustre ceci:

#inclure
Utilisation de Namespace Std;
char char = '1';
int main()

essayer

if (isdigit (entrée))
lancer 10;

Catch (int)

couter << "Digit input is forbidden!" << '\n';

Catch (int)

couter << "Not allowed at all: digit input!" << '\n';

retour 0;

La sortie est:

"L'entrée de chiffres est interdite!"

Blocs d'essai / catch imbriqués:

Les blocs d'essai / capture peuvent être imbriqués. Le programme ci-dessus pour la saisie de caractères non alphanumériques du clavier est répété ici, mais avec le code d'erreur alphabétique imbriqué:

#inclure
Utilisation de Namespace Std;
char char = '*';
int main()

essayer

if (isdigit (entrée))
lancer 10;
essayer

if (isalpha (entrée))
jeter «z»;

attraper (char)

couter << "Character input is forbidden!" << '\n';


Catch (int)

couter << "Digit input is forbidden!" << '\n';

retour 0;

L'erreur alphabétique essai / bloc de capture est imbriquée dans le bloc d'essai du code du chiffre. L'opération de ce programme et l'opération précédente à partir de laquelle il est copié est le même.

NO EXCEPTER SPECICICATEUR

Considérez la fonction suivante:

void fn (const char * str) noexcept

if (islower (str [0]))
jeter «l»;

Remarquez le spécificateur `` NOexcept '' juste après la bonne parenthèse de la liste des paramètres de fonction. Cela signifie que la fonction ne doit pas lancer une exception. Si la fonction lance une exception, comme dans ce cas, elle se compilera avec un message d'avertissement mais ne fonctionnera pas. Une tentative d'exécution du programme appellera la fonction spéciale std :: termine (), ce qui devrait interrompre le programme gracieusement au lieu de simplement lui permettre de s'écraser littéralement.

Le spécificateur NOExcept est sous différentes formes. Ce sont les suivants:

type func () noexcept; : ne permet pas d'expression de lancer
type func () noExcept (true); : permet une expression de lancer
type func () throw (); : ne permet pas d'expression de lancer
type func () noExcept (false); : permet une expression de lancer, qui est facultative
type func (); : permet une expression de lancer, qui est facultative

Vrai ou faux dans les parenthèses peut être remplacé par une expression qui se traduit par une vraie ou une fausse.

La fonction spéciale std :: terminate ():

Si une exception ne peut pas être manipulée, elle doit être refacée. Dans ce cas, l'expression lancée peut ou non avoir un opérande. La fonction spéciale std :: terminate () sera appelée au moment de l'exécution, ce qui devrait arrêter gracieusement le programme au lieu de simplement lui permettre de s'écraser littéralement.

Tapez, compilez et exécutez le programme suivant:

#inclure
Utilisation de Namespace Std;
char char = '1';
int main()

essayer

if (isdigit (entrée))
lancer 10;

Catch (int)

lancer;

retour 0;

Après une compilation réussie, le programme s'est terminé sans s'exécuter et le message d'erreur de l'ordinateur de l'auteur est:

«Terminé appelé après avoir lancé une instance de« int »

Avorté (noyau déversé) »

Conclusion:

La fonction d'exception en C ++ empêche un segment de code d'exécuter en fonction d'une sorte d'entrée. Le programme continue de s'exécuter comme nécessaire. La construction exception (prévention des erreurs) se compose d'un bloc d'essai et d'un blocage. Le bloc d'essai a le segment d'intérêt de code, qui peut être contourné, selon une condition d'entrée. Le bloc d'essai a l'expression de lancer, qui lance un opérande. Cet opérande est également appelé l'exception. Si le type d'opérande et le type du paramètre du bloc de capture sont les mêmes, l'exception est capturée (manipulée). Si l'exception n'est pas capturée, le programme sera résilié, mais soyez toujours en sécurité puisque le segment de code qui devait être exécuté pour donner le mauvais résultat n'a pas été exécuté. Le traitement typique des exceptions signifie le contournement du segment de code et l'envoi d'un message d'erreur à l'utilisateur. Le segment de code est exécuté pour une entrée normale mais contourné pour les mauvaises entrées.