C++ : ​La gestion des erreurs avec les exceptions

Appliquer une garantie forte contre les exceptions

Testez gratuitement nos 1300 formations

pendant 10 jours !

Tester maintenant Afficher tous les abonnements
Travaillez à partir d'un exemple concret. Vous allez apprendre à modifier une classe pour qu'elle propose une garantie forte contre les exceptions.
07:12

Transcription

Nous avons vu que la classe MotsCroises ne proposait pas de garantie forte aux exceptions. Nous allons maintenant justement la mettre à jour pour qu'elle puisse supporter des exceptions, garder sa cohérence et éviter des fuites mémoire, comme on a vu au niveau des constructeurs. Alors pour cela, la première chose à faire, c'est changer ce champ qui lui travaille avec des pointeurs, qui lorsqu'il y a un problème, restent alloués. On va utiliser des pointeurs intelligents et des tableaux, les collections standard qui elles quand elles sont détruites, libèrent la mémoire associée. Donc ici par exemple, je vais utiliser un vecteur de tableau de caractères. On ne peut pas utiliser de vecteur de chaîne parce que notre grille est un peu particulière, nos chaînes de caractères contiennent des zéros terminaux au milieu pour les cases noires. Donc on ne peut pas utiliser std :: string qui ne supporterait pas les zéros terminaux en plein milieu. Ils considéreraient que c'est la fin de la chaîne et on aurait un fonctionnement anormal dans le cas de std :: string justement et plutôt donc des pointeurs uniques. Ce qui est intéressant de voir aussi, c'est l'utilisation de nos pointeurs intelligents dans ce genre de cas particulier, que vous pouvez rencontrer aussi et donc là, des pointeurs uniques sur des tableaux de caractères alloués dynamiquement. Eux vont s'assurer de libérer la mémoire en cas d'exception. Bien sûr, cela va avoir un impact sur zerogrille qui initialise ce tableau. Ici void zerogrille ne retourne plus de char, il va travailler sur notre vecteur. Il faut bien sûr inclure les bibliothèques vector et memory pour le pointeur unique. Et puis aussi, on implémente la sémantique de déplacement. Cette sémantique donc, c'est un point qui est important et il y a une règle qu'on appelle la règle des cinq, que l'on détaille dans le cours sur la sémantique de déplacement dans notre catalogue. Cette règle est une extension de la règle des trois qui dit que lorsqu'on a au moins un destructeur, un constructeur copie ou un constructeur de déplacement, ce qui est le cas, il faut implémenter d'autres membres dont l'opérateur d'affectation. Le plus simple est de le faire avec l'idiome copy and swap. Donc justement, on va implémenter un opérateur d'affectation. Voilà. [ inaudible ] ici. Cet opérateur d'affectation qui retourne par référence est particulier puisqu'il prend dans l'idiome copy and swap par valeur pour justement avoir une bonne garantie sur les exceptions. On va le voir dans son implémentation. On a donc commencé à bien modifier notre classe MotsCroises. Il faut maintenant répercuter ces modifications sur .cpp. Première chose déjà, on a rajouté l'opérateur d'affectation, le mettre ici, voilà. Cet opérateur d'affectation est selon l'idiome copy and swap implémenté en effectuant des swaps, c'est à dire en appelant la fonction swap, en effectuant des déplacements sur la valeur passée ici, ce qui évite toute allocation. En effet, un opérateur d'affectation habituel va faire des allocations éventuellement si la grille de mots croisés que l'on reçoit est plus grande que la grille que l'on contient. Ici comme on a un passage par valeur, je peux me permettre de modifier la valeur qui m'est passée et donc de l'altérer. C'est elle qui prend le risque d'allouer puisque c'est une copie et lorsque je vais faire le déplacement, ici je n'ai aucune allocation donc aucun risque d'exception. Donc c'est un idiome qui permet d'éviter des exceptions qui seraient préjudiciables à notre garantie forte. J'en profite pour mettre à jour le destructeur qui lui est beaucoup plus simple maintenant puisqu'on a tout dans des objets dans des pointeurs uniques, donc la désallocation se fait naturellement. On va remonter sur nos méthodes pour les mettre à jour une par une. Alors ici il n'y a plus d'initialisation de ligne qui est un vecteur qui est initialisé de fait. Il faut plutôt appeler zerogrille qui initialise une grille à zéro et qui retourne void ici. Même chose ici pour notre grille qui va être allouée ligne par ligne avec donc la définition d'un pointeur unique. Pointeur unique donc que l'on alloue, p = unique_ptr. Alors on peut faire un make_unique si on est en c++14 qui permet d'allouer directement (new char [ ] ) et donc je vais refaire _largeur+1 puisqu'on a le dernier zéro terminal en plus. Il faut donc penser à utiliser p et non plus _lignes [ i ], p.get qui nous permet d'avoir l'adresse et un autre .get là, puisque lignes est un vecteur aussi de pointeur unique. Maintenant on peut, une fois qu'on a fait la recopie, et une fois seulement qu'on a fait cette recopie, ajouter donc ce pointeur dans la liste des pointeurs et penser à faire move qui permet de déplacer le pointeur unique puisqu'il n'a pas le droit d'être copié. C'est un pointeur unique, les copies sont interdites. On va s'inspirer de ce code pour faire le zerogrille. Ici donc, on le passe à void puisqu'il est void maintenant et puis on va reprendre un code très similaire sauf qu'ici on aura un memset pour mettre à zéro toute la ligne plutôt que de mettre le contenu d'une autre grille de MotsCroises. Et ici donc le move, on utilise le move du vector qui est très bien fait et donc ici, on n'a plus besoin de faire ça. Par contre on va correctement mettre à jour la largeur de l'autre et la hauteur de l'autre, en faisant ceci, voilà, on les met à zéro si on les a déplacés. Maintenant, il n'y a plus qu'à faire attention au pointeur qui reste puisque on a ici et là des pointeurs uniques mais qui doivent être manipulés comme des vrais pointeurs. Et donc ici, on exécute et là, aucune fuite mémoire. On a eu pourtant une saturation de la mémoire à 150 octets comme toute à l'heure sauf qu'ici la mémoire est libérée correctement puisque tout est dans des objets qui gèrent eux-mêmes la mémoire des pointeurs intelligents des vector. Donc on a une bonne gestion des exceptions. Donc la garantie forte passe souvent par une grande vigilance au moment de l'écriture, le respect des bonnes pratiques, la règle des cinq notamment lorsqu'on utilise la sémantique de déplacement et puis l'utilisation de pointeurs intelligents et de collections standard. Vous avez maintenant tous les éléments pour faire des classes qui proposent une garantie forte.

C++ : ​La gestion des erreurs avec les exceptions

Profitez des nombreux atouts des exceptions pour gérer les erreurs dans vos développements C++. Apprenez à les déclencher, les intercepter, les personnaliser, etc.

56 min (13 vidéos)
Aucun commentaire n´est disponible actuellement
 
Logiciel :
Spécial abonnés
Date de parution :20 oct. 2016

Votre formation est disponible en ligne avec option de téléchargement. Bonne nouvelle : vous ne devez pas choisir entre les deux. Dès que vous achetez une formation, vous disposez des deux options de consultation !

Le téléchargement vous permet de consulter la formation hors ligne et offre une interface plus conviviale. Si vous travaillez sur différents ordinateurs ou que vous ne voulez pas regarder la formation en une seule fois, connectez-vous sur cette page pour consulter en ligne les vidéos de la formation. Nous vous souhaitons un excellent apprentissage avec cette formation vidéo.

N'hésitez pas à nous contacter si vous avez des questions !