La présentation est en train de télécharger. S'il vous plaît, attendez

La présentation est en train de télécharger. S'il vous plaît, attendez

Structures de données IFT-2000 Abder Alikacem Types de données abstraits (2) Semaine 1 Département dinformatique et de génie logiciel Édition Septembre.

Présentations similaires


Présentation au sujet: "Structures de données IFT-2000 Abder Alikacem Types de données abstraits (2) Semaine 1 Département dinformatique et de génie logiciel Édition Septembre."— Transcription de la présentation:

1

2 Structures de données IFT-2000 Abder Alikacem Types de données abstraits (2) Semaine 1 Département dinformatique et de génie logiciel Édition Septembre 2009

3 Plan Exemple dun TDA: une liste ordonnée Utilités Spécifications Implantation Structures de données génériques Gestion des exceptions

4 Introduction Lobjectif de cette partie du cours est de commencer à décrire des représentations des structures de base utilisées en informatique telles les listes. Ces derniers seront vus en termes de types abstraits. Un autre objectif recherché est de donner des exemples de séparations des représentations logiques à travers les TDA des implémentations physiques. Enfin, un dernier objectif est de décrire les outils du langage C++ quon aurait besoin pour implanter les structures de données dans notre cours.

5 Les listes Les listes sont des structures informatiques qui permettent de garder en mémoire des données en respectant un certain ordre: on peut ajouter, enlever ou consulter un élément en début ou en fin de liste, vider une liste ou savoir si elle contient un ou plusieurs éléments. La structure de liste particulièrement souple et dont les éléments sont accessibles à tout moment. Toute suite dinformations inscrites les unes après les autres est une liste. Exemple : liste détudiants, liste dinventaire, liste des absents, …

6 Les listes Une liste est définie comme étant une suite ordonnée déléments. Lordre signifie que chaque élément possède une position dans la liste. Une liste: structure récursive ( a (b ( c (d)))) a b c Une liste peut être vu comme une structure récursive : liste = élément + liste OU liste = vide

7 Liste ordonnée déléments (int) L = L 1 = 8, L 2 = 1, L 3 = 5, L 4 = 4, L 5 = 6 Utilité? Un exemple de liste: une liste ordonnée

8 Réq.#1: 2000 chemises 1000 pantalons 1500 cravates... Réq.#2 Réq.#3 Réq.#1 Liste ordonnée déléments (int) L = L 1 = 8, L 2 = 1, L 3 = 5, L 4 = 4, L 5 = 6 Utilité? liste de réquisitions Un exemple de liste: une liste ordonnée

9 3 2 1 Liste ordonnée déléments (int) L = L 1 = 8, L 2 = 1, L 3 = 5, L 4 = 4, L 5 = 6 Utilité? liste de réquisitions file dattente Un exemple de liste: une liste ordonnée

10 Liste ordonnée déléments (int) L = L1 = 8, L2 = 1, L3 = 5, L4 = 4, L5 = 6 Utilité? liste de réquisitions file dattente Parcours dun graphe

11 x x Liste ordonnée déléments (int) L = L1 = 8, L2 = 1, L3 = 5, L4 = 4, L5 = 6 Utilité? liste de réquisitions file dattente Parcours dun graphe Un exemple de liste: une liste ordonnée

12 Liste ordonnée déléments (int) L = L1 = 8, L2 = 1, L3 = 5, L4 = 4, L5 = 6 Utilité? liste de réquisitions file dattente Parcours dun graphe

13 Manipulations (opérateurs): L L = ? (i.e., L = 0?) x L? L i x = L ? L L + i x L - i L L L - x L = L? L L? lister L L = Opérateurs sur les listes

14 Manipulations (opérateurs): L L L = ? (i.e., L = 0?) x L? L i x = L ? L L + i x L - i L L L - x L = L? L L? lister L L = L = 5 Opérateur: nombre déléments?

15 Opérateur: liste vide? Manipulations (opérateurs): L L = ? L = ? (i.e., L = 0?) x L? L i x = L ? L L + i x L - i L L L - x L = L? L L? lister L L = Non!

16 Opérateur: appartenance Manipulations (opérateurs): L L = ? (i.e., L = 0?) x L? x L? L i x = L ? L L + i x L - i L L L - x L = L? L L? lister L L = 4 L? Oui! 9 L? Non!

17 Manipulations (opérateurs): L L = ? (i.e., L = 0?) x L? L i L i x = L ? L L + i x L - i L L L - x L = L? L L? lister L L = L 1 = 8, L 2 = 1, L 3 = 5, L 4 = 4, L 5 = 6 Opérateur: accès

18 Opérateur: rang (indice) Manipulations (opérateurs): L L = ? (i.e., L = 0?) x L? L i x = L ? x = L ? L L + i x L - i L L L - x L = L? L L? lister L L = 8 1, 1 2, 5 3, 4 4, 6 5, 9 0

19 Opérateur: ajout Manipulations (opérateurs): L L = ? (i.e., L = 0?) x L? L i x = L ? L L + i x L L + i x L - i L L L - x L = L? L L? lister L L = L L + 1 9: L L + 2 9: L L + 3 9: L L + 4 9: L L + 5 9: L L + 6 9: L L + 7 9: <>

20 Opérateur: retrait du rang Manipulations (opérateurs): L L = ? (i.e., L = 0?) x L? L i x = L ? L L + i x L - i L L - i L L L - x L = L? L L? lister L L = L - 1 L: L - 2 L: L - 3 L: L - 4 L: L - 5 L: L - 6 L:

21 Opérateur: retrait délément Manipulations (opérateurs): L L = ? (i.e., L = 0?) x L? L i x = L ? L L + i x L - i L L L - x L L - x L = L? L L? lister L L = L L - 8: L L - 1: L L - 5: L L - 4: L L - 6: L L - 9:

22 Manipulations (opérateurs): L L = ? (i.e., L = 0?) x L? L i x = L ? L L + i x L - i L L L - x L = L? L = L? L L? lister L L = Non! Opérateur: test dégalité

23 Opérateur: inclusion stricte Manipulations (opérateurs): L L = ? (i.e., L = 0?) x L? L i x = L ? L L + i x L - i L L L - x L = L? L L? L L? L L? lister L L = Oui! L = Non!

24 Opérateur: inclusion Manipulations (opérateurs): L L = ? (i.e., L = 0?) x L? L i x = L ? L L + i x L - i L L L - x L = L? L L? L L? L L? lister L L = Oui! L = Oui!

25 Manipulations (opérateurs): L L = ? (i.e., L = 0?) x L? L i x = L ? L L + i x L - i L L L - x L = L? L L? lister L lister L L = 8,1,5,4,6 Opérateur: listage

26 Autres opérateurs? Opérateur: sous-liste

27 Autres opérateurs? sous-liste de L, de i, pour une longueur de n: L[i,n] L = L[2,3] = Opérateur: sous-liste

28 Autres opérateurs? sous-liste de L, de i, pour une longueur de n: L[i,n] concaténation de listes: L + L L = L[2,3] = L = L + L = Opérateur: concaténation

29 Spécifications « langage C » L L + i x prototype de la fonction implantant lopérateur: Liste ajouterListe(Liste l, TypeEl x, int i, int *err); préconditions conditions devant être vraies au départ pour assurer le bon fonctionnement de l opérateur l ne doit pas être pleine et i [1,|L|+1] postconditions conditions étant vraies (observables) après lapplication (correcte) de lopérateur l contient x et *err = OK si les préconditions sont respectées l est inchangée sinon et *err contient: PAM si L est pleine, PERR si i [1,|L|+1] valeur retournée en output de lapplication de l opérateur: l mise à jour ou l inchangée en cas d'erreurs

30 Spécifications « C++ » L L + i x prototype de la méthode implantant lopérateur: void ajouter(TypeEl x, int i) throw(range_error, length_error); préconditions conditions devant être vraies au départ pour assurer le bon fonctionnement de l opérateur La liste ne doit pas être pleine et i [1,|L|+1] postconditions conditions étant vraies (observables) après lapplication (correcte) de lopérateur La liste contient x si les préconditions sont respectées La liste est inchangée sinon et : Exceptions les exceptions lancées par la méthode lors dun problème si L est pleine, si i [1,|L|+1] valeur retournée en output de lapplication de l opérateur: aucune

31 Spécifications version dOxygen L L + i x prototype de la méthode implantant lopérateur: void ajouter(TypeEl x, int i) throw(range_error, length_error); /** * \brief Ajouter un nouvel élément dans la liste * * \pre il y a assez de mémoire pour ajouter l'élément x * \pre la position d'ajout, pos, est comprise entre 1 et |L|+1 * * \post la liste comprend un élément de plus * \post la liste est inchangée sinon * * \exception range_error si la position est erronée * \exception length_error si pas assez de mémoire * */

32 Spécifications du type liste: - i L - i L prototype: Liste enleverListe (Liste l, int i, int *err); préconditions: i [1,|L|] postconditions: l est inchangée si i [1,|L|] avec *err = PERR l contient un élément de moins, lélément L i avec *err=OK, sinon valeur(s) retournée(s): l mise à jour ou inchangée en cas d'erreurs C

33 Spécifications du type liste: - i L - i L prototype: void enlever(int i) throw(range_error); préconditions: i [1,|L|] postconditions: La liste contient un élément de moins, lélément L i si la précondition nest pas satisfaite La liste est inchangée si i [1,|L|] sinon Exception: si la position est erronée valeur retournée: aucune C++

34 Spécifications du type liste: - i L - i L prototype: void enlever(int i) throw(range_error); /** * \brief Enlever lélément en position i dans la liste * * \pre i est compris entre 1 et |L| * * \post la liste comprend un élément de moins * \post la liste est inchangée sinon * * \exception range_error si la position est erronée * */ dOxygen

35 Spécifications du type liste: - L L - x prototype: Liste enleverElListe (Liste l, TypeEl x, int *err); préconditions: Aucune postconditions: l contient un élément x de moins (le premier rencontré), l inchangée si x L et *err = OK valeur retournée: l inchangée si x nappartenait pas à l l mise à jour sinon C

36 Spécifications du type liste: - L L - x prototype: void enleverEl (TypeEl x); préconditions: Aucune postconditions: La liste contient un élément x de moins (le premier rencontré), inchangée si x L Exception aucune valeur retournée: aucune C++

37 Spécifications du type liste: - L L - x prototype: void enleverEl (TypeEl x); /** * \brief EnleverEl dans la liste la première occurrence de x * * \post la liste comprend un élément de moins * \post la liste est inchangée si x à la liste * */ dOxygen

38 Spécification du type liste: L i L i prototype: TypeEl elementListe(Liste l, int i, int *err); préconditions: i [1,|L|] postconditions: l est inchangée avec *Err = OK l est inchangée et *Err = PERR si i [1,|L|] valeur(s) retournée(s): Une copie de L i si la précondition est respectée Une valeur quelconque sinon C

39 Spécification du type liste: L i L i prototype: TypeEl elementPos(int i) throw(range_error); préconditions: i [1,|L|] postconditions: La liste est inchangée si i [1,|L|] La liste est inchangée sinon Exception : Si la position est erronée valeur(s) retournée(s): Une copie de L i si la précondition est respectée Une valeur quelconque sinon C++

40 Spécification du type liste: L i L i prototype: TypeEl elementPos(int i) throw(range_error);; /** * \brief retourner lélément en position i dans la liste * * \pre i est compris entre 1 et |L| * * \post la liste est inchangée * \post lélément en position i est retournée, une valeur quelconque sinon * * \exception range_error si la position i est erronée * */ dOxygen

41 Implantation du type liste ordonnée Implantation par tableau statique

42 Implantation du type liste ordonnée La liste peut être implantée à l'aide d'un tableau. Dans ce cas, il faut prévoir une taille maximum pour le tableau. L'opération d'impression des éléments d'une liste et de recherche d'un élément se font en temps linéaire. La recherche du k-ième élément se fait O(1) i.e. en un temps constant. Cependant les insertions et les suppressions d'éléments sont plus coûteuses. Par exemple, l'insertion à la position 0 nécessite le déplacement de tous les éléments de la liste pour libérer la position 0. Par conséquent la création d'une liste à l'aide de n insertions successives à partir de la position 0 nécessite un temps en O(n 2 ) (pourquoi?). Implantation par tableau

43 /******************************************************************** ModeleImplantationListe.h i.e. modèle dimplantation du type Liste ordonnée Version 1.0 Janvier 2007 (c) IFT Structures de données ********************************************************************/ #ifndef _LISTEC__H #define _LISTEC__H #define MAX_LISTE 100 typedef enum {FAUX, VRAI} Bool;/*le type booléen*/ typedef int TypeEl;/* le type de base de la liste */ typedef struct { TypeEl tab[MAX_LISTE];/* représentation physique de la liste */ int cpt;/* la cardinalité de la liste */ } Liste;/* le type liste ordonnée */ #endif Implantation par tableau En langage C Implantation du type liste ordonnée

44 Création de listes déclaration: Liste L1, L2; initialisation: L1 = initListe(&err); L2 = initListe(&err); Liste initListe(int * err) { Liste l; /*A: Lespace mémoire est suffisant.*/ l.cpt = 0; *err = OK; return l; } En langage C

45 Destruction de listes destruction: detruireListe(L1, &err); detruireListe(L2, &err); Liste detruireListe(Liste l, int * err) { … return l; } En langage C

46 Interface du type Liste Interface dun type abstrait (invariable) /******************************************************************** Liste.h i.e. interface du type Liste ordonnée Version 1.0 Janvier 2007 (c) IFT Structures de données ********************************************************************/ #include "ModeleImplantationListe.h" #define OK 0/* tout est correct */ #define LNI 1/* liste non initialisée */ #define PAM2/* pas assez de mémoire*/ #define PERR 3/* position erronée */ Liste initListe(int *err); /***************************************************************** prototype :Liste initListe(int *err) précondition :… etc.. En langage C

47 Implémentation /******************************************************************** Liste.c Version 1.0 Janvier 2007 (c) IFT Structures de données ********************************************************************/ #include "Liste.h" Liste ajouterListe (Liste l, TypeEl x, int pos, int *err) { /*objectif:ajouter l'élément x à la liste l en position pos méthode:décaler vers la droite tous les éléments à partir de la fin de la liste, jusqu'à ce que pos soit atteint besoins:La liste l, l'élément x, l'indice d'insertion pos et MAX_LISTE, la taille maximale de la liste connu:MAX_LISTE entrée: l, x, pos sortie:La liste l mise à jour (si *err = OK), la liste l inchangée sinon. résultat:*err=OK si les pré sont respectées, PAM si pas assez de place, PERR si la position est erronée hypothèse: Pos est compris entre 1 et la taille de la liste + 1 (|L| + 1) inclusivement, il y a assez de place pour ajouter x. */ … En langage C

48 Implémentation Liste ajouterListe (Liste l, TypeEl x, int pos, int *err) {… if (l.cpt >= MAX_LISTE) { /* La liste est pleine. */ *err = PAM; return l; } /*A: La liste n'est pas pleine */ if ((pos (l.cpt + 1))) { /* Les paramètre fournis sont invalides. */ *err = PERR; return l; } /*A: pos >= 1 et pos <= taille de la liste + 1 */ *err = OK; //etc... return l; } En langage C

49 Implantation du type liste ordonnée En langage C++……

50 Dabord, quelques différences entre C++ et C en ce qui concerne le cours C malloc(sizeof(float)*25) free(x) realloc(x,sizeof(float)*25); typedef struct { // […] } MaStruct; void fonction(MaStruct *m,float x); Aucun équivalent pour « private: », il faut user de discipline. float f(float a, int x, int *err) { if(x

51 Dabord, quelques différences entre C++ et C en ce qui concerne le cours C C++ struct Nombres { Nombres(); void ajout(float nouv_nbr); // etc. private: float x[100]; int n; }; typedef struct { float x[100]; int n; } Nombres; CodeErreur initNombres(Nombres *n); CodeErreur ajoutNombres(Nombres *n, float nouv_nbr); // etc.

52 Dabord, quelques différences entre C++ et C en ce qui concerne le cours C C++ typedef enum { OK, Erreur } CodeErr; typedef struct { int matricule,nb_cours,age; char nom[50]; } Etudiant; typedef struct { Etudiant etudiants[40000]; int n; } Universite; CodeErr initUniversite(Universite *u); CodeErr ajoutUniversite(Universite *u, Etudiant et); int trouve_age(const Universite *u, int matricule); void detruitUniversite(Universite *u); struct Etudiant { public: int matricule,nb_cours,age; char nom[50]; }; struct Universite { public: Universite(); void ajout(Etudiant et); int trouve_age(int matricule) const; ~Universite(); private: Etudiant etudiants[40000]; int nb_etudiants; };

53 Dabord, quelques différences entre C++ et C en ce qui concerne le cours C C++ CodeErr initUniversite(Universite *u) { u->n=0; return OK; } CodeErr ajoutUniversite(Universite *u, Etudiant et) { if(u->n==40000) return Erreur; u->etudiants[u->n++] = et; return OK; } int trouve_age(const Universite *u, int matricule) { int i; for(i=0;i n;i++) if(u->etudiants[i].matricule==matricule) return u->etudiants[i].age; return -1; // Convention pour matricule introuvable. } void detruitUniversite(Universite *u) { } Universite::Universite() { n=0; } void Universite::ajout(Etudiant et) { if(n==40000) throw runtime_error(Luniversité est pleine!); etudiants[n++]=et; } int Universite::trouve_age(int matricule) const { for(int i=0;i

54 Encapsulation. struct (C) vs classe (C++) //Fichier ModeleImplantationListe.h #ifndef _LISTEC__H #define _LISTEC__H #define MAX_LISTE 100 typedef enum {FAUX, VRAI} Bool; typedef struct { int tab[MAX_LISTE]; int cpt; } Liste; #endif //Fichier Liste.h #include "ModeleImplantationListe.h" #include "CodesErreur.h" Liste initListe(int * err); /**/ int tailleListe(Liste l, int *err); /**/ Bool estVideListe(Liste l, int *err); /**/ Liste ajouterListe(Liste l, int x, int pos, int *err); /**/ // etc.. // Fichier Liste.h #include using namespace std; #ifndef _LISTEC__H #define _LISTEC__H #define MAX_LISTE 100 class Liste { private: int tab[MAX_LISTE]; int cpt; public: Liste(); //constructeur ~Liste(); //destructeur void ajouter (int x, int pos); int taille() const ; bool estVide() const; //etc… }; #endif Version de base

55 Note 1 Remarquez que le mot clé const est utilisé à la fin des déclarations de fonction membres de la classe Liste en mode lecture seule, à savoir taille () et estVide(). Afin de mieux protéger un programme, il y a tout intérêt à déclarer comme constantes les fonctions qui ne sont pas censées modifier létat des objets auxquels elles sont liés. On bénéficiera ainsi dune aide supplémentaire du compilateur qui empêchera tout ajout de code modifiant létat de lobjet dans la fonction. Implantation du type liste ordonnée

56 Implantation de la classe Liste en C++ //Liste.cpp #include "Liste.h" Liste::Liste() { cpt = 0; } bool Liste::estVide() const { return taille()==0; } Liste:: ~Liste() { cpt=0; //Note.. } int Liste::taille() const { return cpt; } #include "Liste.h " void Liste::ajouter (int x, int pos) { if(cpt==MAX_LISTE) return; if (pos taille() +1) return; pos--; for (i = (cpt - 1); i >= pos; i--) { tab[i+1] = tab[i]; } tab[pos] = x; cpt++; }

57 Utilisation de la classe Liste //Main.cpp #include "Liste.h" int main() { Liste l; //appel automatique du constructeur l.ajouter(1,1); l.ajouter(2,2); l.ajouter(3,3); if(l.estVide()) cout << "liste vide" << endl; else cout << "liste non vide" << endl; cout << l.taille() << endl; l.~Liste(); //destruction de la liste, inutile… // etc.. return 0; }

58 #ifndef _LISTEC__H #define _LISTEC__H #include using namespace std; #define MAX_LISTE 5 // Le type Liste class Liste{ public: Liste(); //constructeur ~Liste(); //destructeur Liste(const Liste &); //constructeur de copie Liste& operator = (const Liste&); // surcharge de lopérateur = void ajouter(int x, int pos); bool estVide() const; int taille() const; friend ostream& operator << (ostream&, const Liste& p); Liste& operator = (const Liste&); private: int tab[MAX_LISTE]; int cpt; }; #endif Définition de la classe Liste en C++ (version 2) Constructeur de copie Surcharge op. =

59 Le constructeur par copie est une méthode implicite dans toute classe. Cette méthode est appelée automatiquement dans les opérations suivantes : Création et initialisation d une nouvelle instance X I2=I1; X I2(I1); passage d un argument par valeur retour d une fonction return (I); // une copie de I est retournée Constructeur de copie Définition de la classe Liste en C++ (version 2)

60 Constructeur de copie Définition de la classe Liste en C++ (version 2) class Liste { public : Liste (const Liste&); // constructeur par copie... }; Par défaut, cette méthode implicite réalise une copie des valeurs qui correspondent à la section private de la classe. Si l implantation d un objet est dynamique le constructeur par copie, réalisera par défaut une copie de pointeur. ==> Surcharger cet opérateur afin quil crée un vrai clone de l instance qui le déclenche.

61 Liste :: Liste (const Liste& l) { cpt = l.cpt; for (int i=0; i

62 Surcharge de lopérateur = Définition de la classe Liste en C++ (version 2) Liste l1;... L opérateur d affectation est une méthode implicite dans toute classe. Par défaut, il réalise une copie des valeurs qui correspondent à la section private de la classe l1.tab l2.tab Liste l2; l2=l1; Problème : Toute modification du tableau des entiers dans la liste l1 se répercute dans la liste l2 (et inversement)

63 Surcharge de lopérateur = Définition de la classe Liste en C++ (version 2) Liste l1;... Pour réaliser une vraie copie de pile par affectation, il faut surcharger l opérateur implicite l1.tab Liste l2; l2=l1; l2.tab

64 Surcharge de lopérateur = Définition de la classe Liste en C++ (version 2) class Liste { public: Liste operator = (const Liste&); // opérateur d affectation Le comportement habituel de lopérateur = autorise à enchaîner les affectations : l1=l2=l3; => la fonction retourne une référence et l argument est une référence. l1 = l2 <=> l1.operator = (l2);

65 Liste& operator = (const Liste&){ cpt = l.cpt; for (int i=0; i

66 Forme canonique de Coplien On dit qu'une classe est sous forme canonique de Coplien si elle contient les éléments suivants : template class Liste { public: Liste(const int = MAX_LISTE) throw(bad_alloc); // constructeur Liste(const Liste&) throw(bad_alloc); // constructeur de copie ~Liste(); // destructeur Liste & operator = (const Liste &) throw (bad_alloc); //surcharge de = //… Remarque On fera de sorte que toutes les classes que nous Implanterons auront ces méthodes au minimum.

67 #include using namespace std; #pragma warning( disable : 4290 ) #define MAX_LISTE 5 #pragma warning( disable : 4290 ) // Le type Liste class Liste{ public: Liste();//constructeur ~Liste();//destructeur Liste(const Liste&); //constructeur de copie void ajouter(int x, int pos) throw(int); // lancement dun int bool estVide() const; int taille() const; friend ostream& operator << (ostream&, const Liste& p); Liste& operator = (const Liste&); private: int tab[MAX_LISTE]; int cpt; }; Définition de la classe Liste en C++ (version 3.1) Gestion des exceptions Usage dun int

68 void Liste::ajouter (int x, int pos) throw(int) { if (cpt==MAX_LISTE) throw 1; if (pos this->taille() +1) throw 2 ; //… } Implémentation (version 3.1) int main() { Liste l; try //on essaie un ajout{ l.ajouter(1,1); l.ajouter(2,2); l.ajouter(4,8); // erreur.. //… } catch(int& code) { cerr << "ERREUR: " << code << endl; return 0; }.... return 0; }

69 Définition de la classe Liste en C++ (version 3.2) #include using namespace std; #include #pragma warning( disable : 4290 ) #define MAX_LISTE 5 #pragma warning( disable : 4290 ) // Le type Liste class Liste{ public: Liste();//constructeur ~Liste();//destructeur Liste(const Liste&); //constructeur de copie void ajouter(int x, int pos) throw(out_of_range, length_error); bool estVide() const; int taille() const; friend ostream& operator << (ostream&, const Liste& p); Liste& operator = (const Liste&); private: int tab[MAX_LISTE]; int cpt; }; Gestion des exceptions Usage dune classe de la librairie stdexcept

70 void Liste::ajouter (int x, int pos) throw(out_of_range, length_error); { if (cpt==MAX_LISTE) throw length_error("Ajouter:La liste est pleine"); if (pos this->taille() +1) throw out_of_range("Ajouter:Position d'ajout erronée"); //… } Implémentation (version 3.2) int main() { Liste l; try //on essaie un ajout{ l.ajouter(1,1); l.ajouter(2,2); l.ajouter(4,8); // erreur.. //… } catch(exception& e) { cerr << "ERREUR: " << e.what() << endl; return 0; }.... return 0; }

71 Définition de la classe Liste en C++ (version 3.3) #include using namespace std; #pragma warning( disable : 4290 ) #define MAX_LISTE 5 #pragma warning( disable : 4290 ) // Le type Liste class Liste{ public: Liste();//constructeur ~Liste();//destructeur Liste(const Liste&); //constructeur de copie void ajouter(int x, int pos) throw(Erreur); bool estVide() const; int taille() const; friend ostream& operator << (ostream&, const Liste& p); Liste& operator = (const Liste&); private: int tab[MAX_LISTE]; int cpt; }; Gestion des exceptions Usage dune classe Erreur

72 class Erreur: public exception{ public: Erreur(int numero=0,std::string phrase="", int niveau=0) throw() :m_numero(numero),m_phrase(phrase),m_niveau(niveau){} virtual const char* what() const throw(){ return m_phrase.c_str();} int getNiveau() const throw(){ return m_niveau;} int getNumero() const throw(){ return m_numero;} virtual ~Erreur() throw(){} private: int m_numero; //Numéro de l'erreur string m_phrase; //Description de l'erreur int m_niveau; //Niveau de l'erreur }; Définition de la classe Liste en C++ (version 3.3) Suite..

73 void Liste::ajouter (int x, int pos) throw(out_of_range, length_error); { if (cpt==MAX_LISTE) throw Erreur(1, «Ajouter:La liste est pleine", 2); if (pos this->taille() +1) throw Erreur(2, « Ajouter: Position d'ajout erronée",2); //… } Implémentation (version 3.3) int main() { Liste l; try //on essaie un ajout{ l.ajouter(1,1); l.ajouter(2,2); l.ajouter(4,8); // erreur.. //… } catch(const Erreur& e) { cerr<< "ERREUR: "<< e.what()<

74 Note 2 Il faut savoir que vous n'êtes pas le seul à lancer des exceptions. Certaines fonctions standards lancent elles aussi des exceptions. Toutes les exceptions lancées par les fonctions standards dérivent de la classe exception, ce qui permet avec un code générique de rattraper toutes les erreurs qui pourraient potentiellement arriver. Exemple: catch(const std::exception& e) { std::cerr << "ERREUR: " << e.what() << std::endl; } Ceci est possible grâce au polymorphisme. On attrape un objet de type std::exception, mais grâce aux fonctions virtuelles et à la référence (les deux ingrédients), c'est la fonction what() de la classe fille qui sera appelée, ce qui est justement ce que l'on souhaite. :) Gestion des exceptions

75 La bibliothèque standard peut lancer 5 types d'exceptions différents résumés dans le tableau suivant : Nom de la classeDescription bad_alloc Lancée s'il se produit une erreur lors d'un new. bad_cast Lancée s'il se produit une erreur lors d'un dynamic_cast. (On verra plus tard ce que c'est) bad_exception Lancée si aucun catch ne correspond à un objet lancé. bad_typeid Lancée s'il se produit une erreur lors d'un typeid.(On verra plus tard ce que c'est) ios_base::failure Lancée s'il se produit une erreur avec un flux. Gestion des exceptions Note 3

76 Le fichier stdexcept contient 9 classes d'exceptions séparées en 2 catégories, les exceptions "logiques" (logic errors) et les exceptions "d'exécution" (runtime errors). Toutes les exceptions présentées dérivent de la classe std::exception et possèdent un constructeur prenant en argument une chaîne de caractère permettant de décrire le problème. Gestion des exceptions #include

77 Nom de la classe Catégorie Description domain_error logique Lancée s'il se produit une erreur de domaine mathématique. invalid_argument logique Lancée si un des arguments d'une fonction est invalide. length_error logique Lancée si un objet aura une taille invalide. Par exemple si la classe Pile vue précédemment a une taille dépassant la taille de la mémoire. out_of_range logique Lancée si il y a une erreur avec un indice. Par exemple si on essaye d'accéder à une case inexistante d'un tableau. logic_error logique Lancée lors de n'importe quel autre problème de logique du programme. range_error exécution Lancée lors d'une erreur de domaine à l'exécution. overflow_error exécution Lancée si il y a une erreur d'overflow. underflow_error exécution Lancée si il y a une erreur d'underflow. runtime_error exécution Lancée pour tout autre type d'erreur non-prévue survenant à l'exécution. Sinon, vous ne savez pas quoi choisir, prenez simplement runtime_error. Gestion des exceptions #include suite..

78 Programmation générique La classe Liste de tout à lheure se présentait comme suit : class Liste{ public: … private: int tab[MAX_LISTE]; … }; Si lon veut une liste de double? + cest exactement le même code sauf quil faut remplacer le type de la données pouvant être stockée dans un tableau + duplication de code !! Introduction

79 Définition de la classe Liste en C++ (version 4) #include using namespace std; #pragma warning( disable : 4290 ) template class Liste{ public: Liste(); //constructeur ~Liste(); //destructeur Liste(const Liste&); //constructeur de copie void ajouter(T x, int pos)throw(out_of_range, length_error); bool estVide() const; int taille() const; friend ostream & operator << (ostream & f, const Liste & l){ for (int i=0; i

80 Définition de la classe Liste en C++ (version 4) #define MAX_LISTE 5 template class Liste{ public: Liste(); //constructeur ~Liste(); //destructeur void ajouter(T x, int pos)throw(out_of_range, length_error); //… private: T tab[MAX_LISTE]; int cpt; }; Paramètre générique Formel

81 Définition de la classe Liste en C++ (version 4) template class Liste{ public: Liste(); //constructeur ~Liste(); //destructeur void ajouter(T x, int pos)throw(out_of_range, length_error); //… private: T tab[max]; int cpt; }; Paramètres génériques Formels

82 #include "Liste.h" template Liste ::Liste() { cpt = 0; } template bool Liste ::estVide() const { return taille()==0; } template void Liste ::ajouter (T x, int pos) throw(out_of_range, length_error) { … this->tab[pos] = x; this->cpt++; } Implémentation (version 4) Liste.inl

83 Utilisation de la classe Liste générique int main() { Liste l; // ou Liste try{ l.ajouter(1,1);//ajout de 1 en pos =1 l.ajouter(2,2); //ajout de 2 en pos =2 l.ajouter(3,3); //ajout de 3 en pos =3 l.ajouter(4,8); //erreur, position erronée l.ajouter(4,1); //ajout de 4 en pos =1 l.ajouter(5,3); //ajout de 5 en pos =3 l.ajouter(6,6); //erreur, liste pleine } catch(exception &e){ cerr << "ERREUR: " << e.what() << endl; return 0; } … Paramètre générique effectif

84 il faut prévoir le pire cas si grandes fluctuations gaspille despace limitation majeure en ajout déléments besoins variables? Limitations dune implantation par tableau allocation dynamique (de mémoire) Utilité des pointeurs et objets pointées Cours de la semaine prochaine private : int cpt; T tab[max];// implantation dans un tableau };// statique


Télécharger ppt "Structures de données IFT-2000 Abder Alikacem Types de données abstraits (2) Semaine 1 Département dinformatique et de génie logiciel Édition Septembre."

Présentations similaires


Annonces Google