© D. Mathieu
mathieu@romarin.univ-aix.fr
I.U.T.d'Aix en Provence - Département Informatique
Créé le 08/02/2000 -
Dernière mise à jour : 27/03/2001
Remarques préliminaires :
Classe CEditable | exo_01 |
Classe CException | exo_02 |
Classe CDuree ... | exo_03 |
Classe CCptIdent | exo_04 |
Dans l'espace de noms anonyme du fichier exo_01.cxx, recopier la fonction suivante :
void Contenu (const CEditable & Ed) { cout << Ed << endl; } |
Ajouter deux classes CA et CB, dérivées de CEditable, qui ne se distinguent que par leur fonction virtuelle _Edit().
Dans la fonction Exo_01(), instancier les classes CA et CB, et éditer les deux objets au moyen de la fonction Contenu().
Ecrire un fichier Makefile_01. Les fichiers CEditable.h et CEditable.hxx étant dans le répertoire include, différent du répertoire courant, il faut :
Pour simplifier l'écriture, on peut ajouter dans le fichier Makefile_01 la macro suivante :
INCLUDE = $(HOME)/tp/tpC++/include |
Compiler et tester. Vous devez constater que la fonction Contenu() affiche bien le contenu de l'objet réel passé en paramètre effectif.
Corrigés : CEditable.h - CEditable.hxx - exo_01.cxx - Makefile_01
Dans une application, il est probable que nous utilisions simultanément plusieurs classes susceptibles de lever des exceptions. Si nous voulons pouvoir intercepter sélectivement les exceptions en provenance de chacune d'elles, par une succession de blocs catch, il est nécessaire que chacune de ces exceptions soit spécifique de la classe qui la lève.
C'est pourquoi, dans l'exo_05 du TP 6 sur les classes, nous avons montré comment développer la classe CException interne à la classe CDuree. Cependant, en première approximation, toutes les classes d'exceptions sont identiques, et il est inutile de redévelopper leur code à chaque fois (données membres m_Libelle et m_CodErr, et fonctions membres). Cette contradiction est levée par la technique suivante :
namespace nsUtil
{ class CException { // ... }; // CException } // nsUtil namespace nsWorking
// ... }; // CDuree } // nsWorking |
Un second problème subsiste : dans la classe écrite au TP 6, le code d'erreur m_CodErr est d'un type énumératif CodErr_t spécifique de CDuree. Si la classe CException est sortie de la classe CDuree, ce type n'est plus défini.
Une solution consisterait à rendre la classe CException générique, avec le type CodErr_t comme paramètre de généricité. Cela présente deux inconvénients :
Nous retiendrons donc la solution suivante : la donnée membre m_CodErr est de type entier (int), mais les valeurs auxquelles elle sera initialisée sont des constantes de types énumératifs (anonymes) spécifiques de chaque classe.
Puisque les exceptions sont en général affichées, il est naturel de faire dériver la classe CException de CEditable.
En les plaçant dans les fichiers include/CException.h, include/CException.hxx et util/CException.cxx, de nombreuses lignes de code de CException peuvent être récupérées à partir des fichiers dirptr/CDuree.*. Les modifications essentielles à effectuer sont les suivantes :
Les fonctions constructeur, destructeur, what(), GetLibelle() et GetCodErr() peuvent être placées dans le fichier .hxx car elles sont très courtes. En revanche, la fonction _Edit() doit être placée dans le fichier .cxx (4 injections = 4 appels de fonctions)
Fichier include/INCLUDE_H
Ce fichier est destiné à contenir les macros d'utilisation courante dans les fichiers Makefile, en particulier :
COMPILER = g++ -c -I$(INCLUDE) -Wall $*.cxx; |
qui peut remplacer les commandes de compilation de la plupart des fichiers sources (voir macros standard de la commande make).
Fichier Makefile_02
Avant tout travail sur ce fichier, il est fortement recommandé de (re)-lire le document Commande Unix make (le paragraphe intitulé : "Arguments de la commande make" peut être sauté pour le moment).
Puis recopier le fichier Makefile_01 dans Makefile_02.
Remplacer la macro INCLUDE par l'inclusion du fichier INCLUDE_H :
include $(HOME)/tp/tpC++/include/INCLUDE_H |
Ajouter la cible permettant l'éventuel déclenchement (lancement du fichier MakeUtil) de la compilation des fichiers du répertoire util.
Fichier exo_02.cxx
Ce programme est seulement destiné à vérifier que les différents fichiers ci-dessus sont justes, et que le polymorphisme est correctement implémenté pour les classes CEditable et CException.
Dans l'espace de noms anonyme du fichier exo_02.cxx, dériver la classe CExcFille de CException, lui ajouter directement en inline :
Dans la fonction Exo_02(), lever une exception de la classe CExcFille.
Compiler et tester. Vérifier que la fonction main() affiche bien l'exception levée.
Corrigés : exo_02.cxx - Makefile_02 - INCLUDE_H - CException.h - CException.hxx - MakeUtil - CException.cxx
La classe CDuree écrite au cours des TPs précédents (en particulier dans l'exo_04 du TP 6 : les classes), peut être allégée grâce aux nouvelles classes utilitaires développées ci-dessus : CEditable et CException.
Recopier les fichiers dirlstsimple/CDuree.* dans le répertoire courant. Effectuer les modifications suivantes :
Recopier le fichier Makefile_02 dans Makefile_03. Ajouter les macros CDUREE_H et CDUREE_HXX, et la compilation de CDuree.cxx.
Recopier le fichier dirclass/exo_04.cxx dans exo_03.cxx et renommer la fonction Exo_04() en Exo_03(). Ajouter en fin de fonction Exo_03() des instructions qui lèvent les différentes exceptions possibles dans la classe CDuree. Les traiter localement, puis relever la dernière.
Recopier le fichier dirclass/FichDurees dans le répertoire courant.
Compiler et tester. Vérifier que la dernière exception est correctement interceptée par la fonction main().
Corrigés : exo_03.cxx - Makefile_03 - CDuree.h - CDuree.hxx - CDuree.cxx
Dans le prochain TP, nous aurons à utiliser une classe formée d'une paire d'informations :
Dans les fichiers CCptIdent.h et CCptIdent.hxx, écrire la classe CCptIdent, de l'espace de noms nsWorking, ayant les caractéristiques suivantes :
chaine [fréquence] |
Dans la fonction Exo_04() du fichier exo_04.cxx, créer un vector de CCptIdent, ouvrir un fichier source pas trop long (par exemple CCptIdent.h). Dans une boucle jusqu'à fin de fichier :
Trier le vector dans l'ordre croissant (fonction sort() générique de la bibliothèque standard, déclarée dans <algorithm>, décrite dans la Documentation SGI : sort() fournie, et déjà utilisée dans l'exo_04 du TP 4), puis afficher son contenu.
Recopier le fichier Makefile_03 dans Makefile_04. Effectuer les ajouts nécessaires correspondant à la classe CCptIdent.
Compiler et tester.
Corrigés : exo_04.cxx - Makefile_04 - CCptIdent.h - CCptIdent.cxx - CCptIdent.hxx
© D. Mathieu
mathieu@romarin.univ-aix.fr
I.U.T.d'Aix en Provence - Département Informatique