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-10541 Abder Alikacem Programmation orienté objet en C++ Module 2 Département dinformatique et de génie logiciel Édition Septembre.

Présentations similaires


Présentation au sujet: "Structures de données IFT-10541 Abder Alikacem Programmation orienté objet en C++ Module 2 Département dinformatique et de génie logiciel Édition Septembre."— Transcription de la présentation:

1

2 Structures de données IFT Abder Alikacem Programmation orienté objet en C++ Module 2 Département dinformatique et de génie logiciel Édition Septembre 2009

3 Plan Introduction au mondes des objets: les concepts Le concept d'Objet Les principes de lApproche Orientée Objet Les relations entre Objets Quelques définitions Principe de lencapsulation Classes et objets Les modèles (templates) Programmation générique : introduction, exemples Déclaration des modèles Fonctions et méthodes génériques Instanciation Spécialisation Compilation séparée Traitement des exceptions

4 Le concept dobjet (1/3) Exemple : une personne, une voiture, une procédure, une loi,... Objet : abstraction du monde réel entité possédant un état (information) offrant des services / opérations pour examiner / modifier son état (comportement) Modèle Orienté-Objet (OO) dune application : définition dun ensemble dobjets coopérants - communicants - et concurrents - vivants indépendamment les uns des autres

5 Le concept dobjet (2/3) Objet = identité + état + comportement Exemple : la voiture 1875 WC 31 état : immatriculation, kilométrage, vitesse instantanée, état interne… services / opérations : accesseurs : kilométrage?, immatriculation?... modificateurs : démarrer, sarrêter, se déplacer, tomber en panne, être réparée... Essentiel : un objet n'est manipulable qu'à travers son interface i.e. ses opérations publiques

6 Le concept d'objet (3/3) Tout objet a une durée de vie finie : il naît, vit et meurt ! Tout objet est en relation avec d'autres objets : relations statiques : (relativement) stables dans le temps relations dynamiques : brèves, limitées à la communication Tout objet peut changer de forme - sous certaines conditions - au cours de son existence : principe de polymorphisme

7 Principes sur lesquels reposent les Objets Encapsulation : regroupement des informations d'état et de comportement sous un nom unique Masquage d'information : on ne connaît pas la structure de l'information Interface : seuls les services publics (offerts à l'extérieur) sont utilisables Envoi de messages : les objets communiquent par messages Durée de vie limitée : dépendante du contexte

8 Les relations entre Objets Relations statiques : composition / agrégation : traduit l'assemblage généralisation / spécialisation : permet la réutilisation association n-aire : relation classique Relations dynamiques : communication : échange de données signal : échange de stimuli

9 Généralisation / spécialisation Généralisation : a posteriori pour favoriser la réutilisation future Spécialisation : c'est de la réutilisation en extension : ajout de nouvelles propriétés en compréhension : modification de propriétés Conséquences : Polymorphisme : possibilité pour une instance de changer de classe tout en restant dans la même hiérarchie Héritage simple / multiple

10 Représentation d'objet kilométrage :... vitesse :... immatriculation :... kilométrage? démarrer tomber en panne... La voiture de Jean Son nom Un objet Son état Opération privée Opération publique

11 Quelques définitions Classe = regroupement d'objets ayant des propriétés (état et/ou comportement et/ou relations) communes Classe = moule qui décrit la structure interne d'un ensemble d'objets Classe = abstraction qui n'a de sens qu'à la compilation Objet = un instance d'une classe Objet = instance qui n'a d'existence qu'à l'exécution

12 Propriétés des objets Unicité : un objet n'est instance que d'une classe et d'une seule une instance a une identité (interne) unique Durée de vie : une instance doit être déclarée, puis définie en fonction du contexte. un objet vit sa vie puis meurt. la durée de vie peut être très courte, très grande ! Polymorphisme : un objet peut changer de forme au cours de sa vie ! Concurrence : les objets évoluent indépendamment les uns des autres

13 Conception Orientée Objet Identification des classes à réutiliser ou à concevoir : utilisation dune méthode OO pour la conception et la définition des hiérarchies de classes à utiliser ou à développer Construction de lApplication OO : transformation de la conception de lapplication en un ensemble dobjets concurrents et coopérants Deux étapes fondamentalement différentes :

14 Intérêt des Objets Maîtrise de la complexité : l'encapsulation permet de se concentrer sur un(e) objet(classe) et un(e) seul(e) il est possible de tester de façon quasi exhaustive un objet Evolution facilitée : rajouter de nouveaux objets est simplifié. On les raccroche aux modèles déjà construits par spécialisation Réutilisation : vraiment possible à cause des classifications induites par la relation de spécialisation / généralisation !...

15 Inconvénients de l'approche OO Tout n'est pas objet : se méfier des chapelles et des gourous ! Tester un ensemble un système OO est difficile ! Penser objet oblige à changer de mentalité !

16 Encapsulation, polymorphisme et héritage Encapsulation Le rassemblement des données et du code les utilisant dans une entité unique (objet). La séparation nette entre la partie publique d'un objet (ou interface) seule connue de l'utilisateur de la partie privée ou implémentation qui reste masquée. Polymorphisme Une méthode peut adopter plusieurs formes différentes. Héritage Possibilité de définir des familles de classes traduisant le principe de généralisation / spécialisation. « La classe dérivée est une version spécialisée de sa classe de base »

17 Encapsulation et abstraction L'encapsulation Consiste à masquer l'accès à certains attributs et méthodes d'une classe. Pourquoi masquer? Cacher les détails d'implémentation des objets à l'utilisateur permet de modifier, par exemple la structure de données interne d'une classe (remplacer un tableau par une liste chaînée) sans pour autant entraîner de modifications dans le code de lutilisateur, linterface nétant pas atteinte. Abstraction de données La structure d'un objet n'est pas visible de l'extérieur, son interface est constituée de messages invocables par un utilisateur. La réception d'un message déclenche l'exécution de la méthode correspondant à ce message. Abstraction procédurale Du point de vue de l'extérieur (cest-à-dire en fait du client de lobjet), l'invocation d'un message est une opération atomique. L'utilisateur n'a aucun élément d'information sur la mécanique interne mise en œuvre. Par exemple, il ne sait pas si le traitement requis a demandé lintervention de plusieurs méthodes ou même la création dobjets temporaires etc.

18 Droits daccès En C++, on choisit les paramètres daccès aux membres dune encapsulation à l'aide des mots clés : private : les membres privés ne sont accessibles que par les fonctions membres de la classe. protected : les membres protégés sont comme les membres privés. Mais ils sont aussi accessibles par les fonctions membres des classes dérivées. public : les membres publics sont accessibles par tous. La partie publique est appelée interface. Les mots réservés private, protected et public peuvent figurer plusieurs fois dans la déclaration de la classe. Le droit d'accès ne change pas tant qu'un nouveau droit n'est pas spécifié.

19 Les différents type dencapsulation Il existe différents types dencapsulation : struct Classe1 { /*... */ }; tous les membres sont par défaut d'accès public par défaut. union Classe2 { /*... */ }; tous les membres sont d'accès public par défaut. class Classe3 { /*... */ }; tous les membres sont d'accès private par défaut. C'est cette dernière forme qui est utilisée en C++ pour définir des classes.

20 Principe de la conception orienté objet Approche traditionnelle Organiser autour du traitement Algorithmes + Structures de données = Programme Fonction 1 Structures de données Fonction 2 Fonction 3 Fonction n

21 Principe de la conception orienté objet Organiser autour des données à manipuler Données Fonctions de manipulations et de traitements Objet

22 Objet en C++ typedef struct { int jour; int mois; int année; } Date; void initData(Data d,int j,int m,int a){ d.jour=j; d.mois=m; d.année=a; } int main(){ Date d; initData(d,2,2,2004); return 0; } Class Date { public : void initData(int j,int m,int a); protected: int _jour; int _mois; int _année; }; Date::initData(int j,int m,int a){ _jour=j; _mois=m; _année=a; } int main(){ Date d; d.initData(2,2,2004); return 0; } Programme C Programme C++

23 Interface dune classe (fichier.h) Section public Attributs public Méthodes public Constructeur Destructeur Fonction daccès Section protected Attributs et méthodes accessibles par les membres de la classe et des classes dérivées Section private Attributs et méthodes accessibles uniquement par les membres de la classe class Date { public : int var1; Date(); ~Date(); void initialiser(int j,int m,int a); void afficher(); int getJour(); int getMois(); int getAnnee(); setJour( int j); setMois(int m); setAnnee(int a); protected: int _jour; int _mois; int _année; void _test(); private: };

24 Implantation dune classe (fichier.cpp) Définition des méthodes de la class : Constructeur Destructeur Fonction daccès Date::Date(){ _jour=0; _mois_0; _annee=0; } Date::~Date(){} void Data::afficher(){ cout << "la date : " << _jour ; cout << "/" << _mois ; cout << "/" << _annee << endl; } int Data::getJour() {return _jours;} int Data::getMois() {return _mois;}; int Data::getAnnee(){return _annee;} Data::setJour(int j) {_jour =j;} Data::setMois(int m) {_mois =m;} Data::setAnnee(int a){_annee=a;}

25 Réutilisabilité On cherche à écrire des objets réutilisables. On aimerait concevoir une classe qui modélise une pile de portée générale : une pile nimporte quels composants. ==> Concevoir une classe générique pile Pcar; pile Ppersonne;

26 Facteur de qualité dun logiciel Réutilisabilité Possibilité d obtenir toutes les occurrences d une classe s appliquant à différents types, en ne décrivant quune seule fois la classe. Une classe décrit une famille d objets : Cohérente Lisible Extensible Réutilisable

27 Programmation générique Lidée de base est de passer les types de données comme paramètres pour décrire des traitements très généraux (« génériques »). Il sagit donc dun niveau dabstraction supplémentaire. De tels modèles de classes/fonctions sappellent aussi classes/fonctions génériques ou patrons (chablons), ou encore « template ». Vous en connaissez déjà sans le savoir. Par exemple la « classe » Vector de la STL nest en fait pas une classe mais un modèle de classes : cest le même modèle que lon stocke des char (vector ), des int (vector ), ou tout autre objet.

28 Programmation générique Prenons un exemple simple pour commencer : une fonction échangeant la valeur de 2 variables. Par exemple avec 2 entiers vous écririez une fonction comme : // échange la valeur de ses arguments void echange(int& i, int& j) { int tmp(i); i = j; j = tmp; } Mais vous vous rendez bien compte que vous pourriez faire la même chose (le même algorithme) avec deux double, ou même deux objets quelconques, pour peu quils aient un constructeur de copie (Obj tmp(i);) et un opérateur de copie (operator=). Exemple simple pour commencer

29 Programmation générique Lécriture générale serait alors quelque chose comme : // échange la valeur de ses arguments void echange(Type& i, Type& j) { Type tmp(i); i = j; j = tmp; } où Type est une représentation générique du type des objets à échanger. La façon exacte de le faire en C++ est la suivante : // échange la valeur de ses arguments template void echange(Type& i, Type& j) { Type tmp(i); i = j; j = tmp; } Exemple suite…

30 Programmation générique On pourra alors utiliser la fonction echange avec tout type/classe pour lequel le constructeur de copie et lopérateur daffectation (=) sont définis. Par exemple : int a(2), b(4); echange(a,b); double da(2.3), db(4.5); echange(da,db); vector va, vb;... echange(va,vb); string sa("ca marche"), sb("coucou"); echange(sa, sb); Exemple suite…et fin

31 Programmation générique Second exemple dune fonction générique template X min (const X& A,const X& B){ if (A> i,j; int m=min (i,j);... } L opérateur < doit être surchargé dans les classes qui utiliseront le modèle min Le compilateur instancie une fonction int min (const int&, const int&)

32 Programmation générique Généralisation aux classes Une classe générique est une classe avec un template. Même principe que les fonctions génériques. template class Nb{ public : T a, b; T add (){ return a+b}; }; Nb N; N.a = 1; N.b = 2; cout << N.Add() << endl;

33 Programmation générique On pourrait par exemple vouloir créer une classe qui réalise une paire dobjets quelconques : template class Paire { public: Paire(const T1& un, const T2& deux) : premier(un), second(deux) {} virtual ˜Paire(){} T1 get1() const { return premier; } T2 get2() const { return second; } void set1(const T1& val) { premier = val; } void set2(const T2& val) { second = val; } protected: T1 premier; T2 second; }; Généralisation aux classes

34 Programmation générique et par exemple créer la classe « paire string–double » : Paire ou encore la classe « paire char–unsigned int » : Paire Note : un tel modèle de classe existe dans la STL : pair. Les modèles de classes sont donc un moyen condensé décrire plein de classes potentielles à la fois. Généralisation aux classes

35 Programmation générique Pour déclarer un modèle de classe ou de fonction, il suffit de faire précéder sa déclaration du mot clé template suivit de ses arguments (qui sont donc des noms génériques de type) suivant la syntaxe : template Exemple template class Paire {... Déclaration dun modèle Le paramètre générique effectif d une classe peut être un identificateur de type prédéfini ou un identificateur de classe.

36 Programmation générique Pour déclarer un modèle de classe ou de fonction, il suffit de faire précéder sa déclaration du mot clé template suivit de ses arguments (qui sont donc des noms génériques de type) suivant la syntaxe : template Exemple template class Paire {... Les types ainsi déclarés (paramètres du modèle) peuvent alors être utilisés dans la définition qui suit, exactement comme tout autre type. Note : on peut aussi utiliser le mot class à la place de typename, par exemple : template class Paire {... Déclaration dun modèle

37 Programmation générique Si les méthodes dun modèle de classes sont définies en dehors de cette classe, elle devront alors aussi être définies comme modèle et être précédées du mot clé template, mais......il est de plus absolument nécessaire dajouter les paramètres du modèle (les types génériques) au nom de la classe [ pour bien spécifier que dans cette définition cest la classe qui est en modèle et non la méthode. ] Exemple template class Paire { public: Paire(const T1&, const T2&);... }; // définition du constructeur template Paire ::Paire(const T1& un, const T2& deux) : premier(un), second(deux) { } Définitions externes des méthodes de modèles de classes

38 Programmation générique La définition des modèles ne génère en elle-même aucun code : cest juste une description de plein de codes potentiels. Le code nest produit que lorsque tous les paramètres du modèle ont pris chacun un type spécifique. Lors de lutilisation dun modèle, il faut donc fournir des valeurs pour tous les paramètres (au moins ceux qui nont pas de valeur par défaut). On appelle cette opération une instanciation du modèle. Linstanciation peut être implicite lorsque le contexte permet au compilateur de décider de linstance de modèle à choisir. Par exemple, dans le code : double da(2.3), db(4.5); echange(da,db); il est clair (par le contexte) quil sagit de linstance echange du modèle template void echange(T&,T&); quil faut utiliser. Instanciation des modèles

39 Programmation générique Mais dans la plupart des cas, on explicite linstanciation lors de la déclaration dun objet. Cest ce qui vous faites lorsque vous déclarez par exemple vector tableau; Il suffit dans ce cas de spécifier le(s) type(s) désiré(s) après le nom du modèle de classe et entre <>. Linstanciation explicite peut aussi être utile dans les cas où le contexte nest pas suffisamment clair pour choisir. Par exemple avec le modèle de fonction template Type monmax(const Type& x, const Type& y) { if (x < y) return y; else return x; } lappel monmax(3.14, 7); est ambigu. Il faudra alors écrire monmax (3.14, 7); Instanciation des modèles

40 Programmation générique Les modèles de fonctions peuvent très bien être surchargés comme les fonctions usuelles (puisque, encore une fois, ce sont juste une façon condensée décrire plein de fonctions à la fois). Par exemple : template void affiche(const Type& t) { cout << "Jaffiche " << t << endl; } // surcharge pour les pointeurs : on préfère ici écrire // le contenu plutôt que ladresse. template void affiche(Type* t) { cout << "Jaffiche " << *t << endl; } Note : on aurait même pu faire mieux en écrivant : template void affiche(Type* t) { affiche (*t); } qui fait appel au premier modèle. Modèles, surcharge et spécialisation

41 Programmation générique Mais les modèles (y compris les modèles de classes) offrent un mécanisme supplémentaire : la spécialisation qui permet de définir une version particulière dune classe ou dune fonction pour un choix spécifique des paramètres du modèle. Par exemple, on pourrait spécialiser le second modèle ci-dessus dans le cas des pointeurs sur des entiers : template<> void affiche (int* t) { cout << "Jaffiche le contenu dun entier: " << *t << endl; } La spécialisation dun modèle (lorsquelle est totale) se fait en : ajoutant template<> devant la définition nommant explicitement la classe/fonction spécifiée Cest le après affiche dans lexemple ci-dessus. Modèles, surcharge et spécialisation

42 Programmation générique template class Paire {... }; // spécialisation pour les paires template<> class Paire { public: Paire(const string& un, int deux) : premier(un), second(deux) {} virtual ˜Paire() {} string get1() const { return premier; } int get2() const { return second; } void set1(const string& val) { premier = val; } void set2(int val) { second = val; } // une méthode de plus void add(int i) { second += il } protected: string premier; int second; }; Exemple de spécialisation de classe

43 Programmation générique Note 1 : La spécialisation peut également sappliquer uniquement à une méthode dun modèle de classe sans que lon soit obligé de spécialiser toute la classe. Utilisée de la sorte, la spécialisation peut savérer particulièrement utile. Note 2 : La spécialisation nest pas une surcharge car il ny a pas génération de plusieurs fonctions de même nom (de plus que signifie une surcharge dans le cas dune classe ?) mais bien une instance spécifique du modèle. Note 3 : il existe aussi des spécialisations partielles (de classe ou de fonctions), mais cela nous emmènerait trop loin dans ce cours. Spécialisation: remarques

44 Exemple 2 template // Le paramètre entier max_size a la valeur 200 par défaut. class pile { public:typedef T value_type; private: T* laPile ; int sommet ; public: pile() : sommet(0) { laPile = new T [taille_max] ; } ~pile() { delete [] laPile ; } void empiler ( T c ) { laPile[ sommet++ ] = c ; } //... }; Programmation générique

45 Retour sur le typename Le mot clef typename indique que le mot suivant doit être considéré comme un type. Cest le cas dans une déclaration template (où typename peut aussi être remplacé par class) et dans les cas où il y aurait ambiguïté ou si le type nest pas encore instancié (paramètre dun autre type, lui-même template). template class SacADos { // P::value_type nest pas encore un type puisque T, na pas été instancié // Il faut donc lindiquer au compilateur typedef typename P::value_type T_values;... }; Programmation générique

46 Fonctions et méthodes génériques template permet aussi de déclarer des fonctions génériques, voire des fonctions membres génériques dune classe générique. Cependant, ici, la spécification entre nest pas requise à lappel car déduite des paramètres effectifs. class pile { template void empiler(const T& a);.... }; template void explorer(const X& p) {... }; int main() { pile p ; // instanciation dune pile. char c = a; // Ces appels sont valides. // Dans le premier cas char est déduit //du type de c. p.empiler(c); explorer( p ); return 0; } Programmation générique

47 Il est possible de créer des Tableaux d'entiers, de les manipuler comme les variables d'un type intégré et de les passer en paramètre sans avoir à fournir la taille comme paramètre supplémentaire. Cependant notre solution ne fonctionne que pour des Tableaux d'entiers. Que se passe-t-il si on avait besoin de Tableaux de doubles ou de chaînes de caractères? On voudrait pouvoir créer des Tableaux de types arbitraires sans avoir à définir une classe distincte pour chacun d'eux. Cela peut être fait à l'aide des modèles (templates). Exemple 3 Programmation générique

48 template class Tableau{ private: int nbelements; int *T; public: Tableau(int); Tableau(const Tableau&); ~Tableau() {delete[] T;}; int longueur() const {return nbelements;}; elem& operator[](int) const; Tableau& operator=(const Tableau&); }; Rappel: on peut écrire template outemplate Programmation générique

49 template Tableau ::Tableau(int n) { T=new elem[n]; nbelements=n; } template Tableau ::Tableau(const Tableau &tab) { T=new elem[tab.nbelements]; (*this)=tab; } template elem& Tableau ::operator[](const int i) const { return T[i]; } Programmation générique

50 template Tableau & Tableau ::operator=(const Tableau &tab) { if (nbelements

51 La définition de la classe est précédée de templace qui indique que l'on défini un modèle et qu'un type elem apparaît en argument dans la déclaration de Tableau. On peut alors déclarer un tableau d'entiers ou de double de la façon suivante: Tableau iTab(100); Tableau dTab(20); Programmation générique

52 Les modèles ne sont pas retreints aux classes comme on la déjà vu et comme l'illustre les exemples suivants: template void echanger(C &A, C &B) { C tmp=A; A=B; B=tmp; } template void print(const Tableau & t) { for (int i=0; i

53 La fonction echanger ne peut être utilisée que par une classe C possédant un constructeur de copie et un opérateur d'affectation. La fonction print nécessite que l'opérateur << soit défini pour les objets de type elem. On peut appeler ces fonctions de la façon suivante: int a=0, b=1; double x=1.0, y=2.3; Tableau A(20), B(30); Tableau C(100) // // initialisation de A, B et C // echanger(a,b); echanger(x,y); echanger(A,B); print(A); print(B); print(C); Programmation générique

54 Les modèle de classes doivent nécessairement être définis au moment de leur instanciation afin que le compilateur puisse générer le code correspondant. Ce qui implique, lors de compilation séparée, que les fichiers den-tête (.h) doivent contenir non seulement la déclaration, mais également la définition complète de ces modèles !! On ne peut donc pas séparer la déclaration de la définition dans différents fichiers... Ce qui présente plusieurs inconvénients : Les mêmes instances de modèles peuvent être compilées plusieurs fois, et se retrouvent en de multiples exemplaires dans les fichiers exécutables. On ne peut plus cacher leurs définitions (par exemple pour des raisons de confidentialité, protection contre la concurrence, etc...) Modèles de classe et compilation séparée

55 Programmation générique Notez également que les fichiers contenant des modèles ne sont pas des fichiers sources classiques, puisque sans instanciation, ils ne génèrent aucun code machine. Pour résoudre ces problèmes, le langage C++ donne en principe la possibilité dexporter les définitions des modèles dans des fichiers complémentaires à laide de la directive export. Malheureusement celle-ci nest pour linstant (à ma connaissance) pas gérée par les compilateurs actuels : warning: keyword export not implemented, and will be ignored En létat, il faut donc malheureusement joindre prototype et définitions des modèles dans les mêmes fichiers den-tête. Le seul « point noir » des templates est donc lié à la faiblesse des compilateurs actuels qui ne gèrent pas la directive export. Modèles de classe et compilation séparée

56 Programmation générique Déclarer un modèle de classe ou de fonction : template Définition externe des méthodes de modèles de classes : template NomClasse ::NomMethode(... Instanciation : spécifier simplement les types voulus après le nom de la classe/fonction, entre <> (Exemple : vector ) Spécialisation (totale) de modèle pour les types type1, type2... : template<> NomModele...suite de la declaration... Compilation séparée : pour les templates, il faut tout mettre (déclarations et définitions) dans le fichier den-tête (.h). Templates

57 Le traitement des exceptions Le C++ contient un mécanisme très utile pour traiter les erreurs et autres exceptions. Lorsqu'une erreur est détectée, il est possible de transmettre (throw) un objet à une partie du code qui reçoit (catch) l'objet et traite l'erreur. Considérons, par exemple, la fonction operator[] de la classe Tableau. Il Serait prudent de vérifier la valeur de l'opérande afin de s'assurer qu'elle corresponde bien à un indice valide du tableau. Si tel n'est pas le cas, que doit faire la fonction? Elle ne dispose pas de l'information nécessaire pour traiter elle-même l'erreur et ne peut pas signaler l'erreur par une valeur de retour ou un paramètre. Pour régler ce problème nous allons ajouter un membre publique et modifier la fonction operator[].

58 Le traitement des exceptions template class Tableau{ elem nbelements; elem *T; public: struct erreur_indice { int indice; erreur_indice(int i){indice=i;}; }; Tableau(int); Tableau(const Tableau&); ~Tableau() {delete[] T;}; int longueur() const {return nbelements;}; elem& operator[](int) const; Tableau& operator=(const Tableau&); };

59 Le traitement des exceptions template elem& Tableau ::operator[](const int i) const { if (i =nbelements) throw erreur_indice(i); return T[i]; } Nous avons ajouté à Tableau la définition d'une structure afin de définir un type d'erreur correspondant aux dépassement des limites. En C++ une structure est exactement comme une classe sauf que par défaut les membres sont publiques. Si operator[] détecte une erreur, il utilisera le constructeur de erreur_indice pour créer un objet qu'il transmettra via l'instruction throw. L'instruction throw se comporte un peu comme l'instruction return sauf qu'elle cherche dans la pile des appels de fonctions celle qui demande à recevoir l'objet.

60 Le traitement des exceptions Exemple: template void initialise(Tableau & t, const elem& E) { for (int i=0; i<=t.longueur(); i++) t[i]=E; } int main() { Tableau T(100); try { initialise(T,0); } catch(Tableau ::erreur_indice e) { cerr<<"Erreur d'indice: <

61 Le traitement des exceptions La fonction main() utilise les mots clefs try et catch pour indiquer qu'elle appelle la fonction initialise et qu'elle désire traiter les erreurs de type Tableau ::erreur_indice. Au dernier tour de boucle de initialise, l'indice i aura dépassé les limites du tableau et Tableau ::operator[] transmettra un objet de type Tableau ::erreur_indice qui sera reçu par la fonction main().

62 Le traitement des exceptions Plusieurs catch peuvent apparaître après un try afin de recevoir et traiter plusieurs types d'erreurs. L'expression catch(...) permet de recevoir tous les types d'erreurs non capturés par les catch précédents: try{ instructions } catch(type 1){ instructions } catch(type 2){ instructions } catch(...){ instructions }


Télécharger ppt "Structures de données IFT-10541 Abder Alikacem Programmation orienté objet en C++ Module 2 Département dinformatique et de génie logiciel Édition Septembre."

Présentations similaires


Annonces Google