Vous êtes sur la page 1sur 80

Langage C++

Année universitaire : 2019/2020


Plan
 Méthodes constantes
 Protection des données
 Le pointeur « this »
 Liste d’initialisation de constructeur
 Attributs constants
 Attributs références
 Attributs de classe « static »
 Méthodes de classe « static »

2
Méthodes constantes
Parmi les méthodes d'une classe, il est possible de
distinguer :
• celles qui modifient les attributs d'un objet ;
• celles qui ne modifient aucun attribut ("méthodes
constantes").
Les méthodes "constantes" ne font pas d'accès "en écriture".
Le mot réservé const doit figurer dans leur déclaration et
dans leur définition, après la liste des arguments.

3
Méthodes constantes
Fichier Point.h Fichier Point.cpp

class Point void Point::setNumero (int n)


{ {
double x, y; numero = n;
int numero; }
public: double Point::norm() const
void setNumero (int n); {
double norm() const; return sqrt (x*x + y*y);
}; }

4
Méthodes constantes

Les constructeurs et les destructeurs ne peuvent


être déclarés const.

Parmi les méthodes d'une classe, les méthodes


constantes forment une classe d'équivalence :
une méthode constante ne peut appeler que des
méthodes constantes.

5
Méthodes constantes
class Avion
{
Vector3D position;
double masse;
Aerodynamique *aero;
public:
Vector3D getPosition() const;
void setPosition(Vector3D xyz);
double getMasse() const;
void setMasse(double m);
const Aerodynamique* getAero() const;
void setAero(Aerodynamique *a); };

6
Protection des données
Donner un accès « protected » ou « private »
aux attributs, écrire des méthodes
accesseurs, utiliser les fonctions « const »
sont les moyens à utiliser pour protéger les
données d'un objet (encapsulation).

7
Protection des données
Fichier Point.h
class Point
{
private:
double x, y;
int numero;
double norm() const;
double diff();
public:
void setNumero (int n);
void show() const; };

8
Exercice : Protection des données
Que pouvez-vous proposer pour sécuriser la classe suivante ?
class Machin
{
public :
double truc;
int machin;
double calcule() {return truc*machin;}
};
Attention, on précise qu’il ne faut pas pour autant diminuer les possibilités d’accès
offertes à l’utilisateur de cette classe.
Tester les modifications dans un petit programme.

9
Le pointeur «  this »
Chaque méthode d'objet dispose en fait d'un
argument supplémentaire, ajouté
automatiquement par le compilateur. Cet
argument est un pointeur du nom de
« this », vers l'objet à qui est appliqué la
méthode.

10
Le pointeur «  this »

Fichier Point.h Fichier Point.cpp


class Point void Point::setNumero (int n)
{ {
private: this->numero = n;
double x, y; }
int numero; void Point::show() const
public: {
void setNumero (int n); cout << "Adresse : " << this
void show() const; << "\nX : " << this->x
double norm() const; << "\nY : " << this->y
}; << "\nNorm : " << this->norm();
}

11
Liste d’initialisation de constructeur
La définition d'un constructeur peut comporter, en en-tête,
ce qu'on appelle une liste d'initialisation de constructeur,
qui figurerait sinon dans le corps.
Fichier Point.h Fichier Point.cpp

class Point #include "Point.h"


{ Point::Point(int n)
double x, y; : x(0.0), y(0.0), numero(n)
int numero; {}
public: Point::Point (double xx, double
Point(int n); yy)
Point(double xx, double yy); : x(xx), y(yy), numero(0)
}; {}
12
Liste d’initialisation de constructeur
La liste est introduite par deux points (:) et
comporte des couples noms d'attributs -
valeur. Chaque attribut ne peut apparaître
au maximum qu'une seule fois.

13
Liste d’initialisation de constructeur
Les valeurs d'initialisation ne se limitent pas aux
constantes, il peut s'agir d'expressions complexes:
Fichier Polynom.h Fichier Polynom.cpp

class Polynom #include "Polynom.h"


{ Polynom::Polynom()
int degre; : degre(0), coeff(NULL)
double *coeff; {}
public: Polynom::Polynom(int n)
Polynom(); : degre(n), coeff(new double[n+1])
Polynom(int n); {}
Polynom(const Polynom &p); }; Polynom::Polynom(const Polynom &p)
: coeff(new double[degre+1]),
degre(p.degre)
{
for (int i=0; i<=degre; i++) 14
coeff[i] = p.coeff[i]; }
Liste d’initialisation de constructeur
Dans certains cas, la liste d'initialisation n'est
pas une simple alternative, elle doit être
obligatoirement utilisée :
• initialisation d'attributs constants;
• initialisation d'attributs références;
• initialisation d'attributs objets.

15
Attributs constants

Il est possible de déclarer constants (const) les


attributs d'un objet. Durant la vie de l'objet,
ceux-ci ne pourront changer.
Les attributs constants doivent être initialisés
dans la liste d'initialisation du constructeur.

16
Attributs constants

Fichier Avion.h Fichier Avion.cpp


class Avion Avion::Avion()
{ : masse(0.0), sRef(0.0),
Vector3D position; coeffAxial(0.0)
Vector3D vitesse; {
double masse; position.setZero();
const double sRef; vitesse.setZero();
const double coeffAxial; }
public: Avion::Avion(double s, double ca,
Avion(); double m, Vector3D pos,
Avion(double s, double ca, Vector3D vit)
double m, Vector3D pos, : position(pos), vitesse(vit),
Vector3D vit); masse(m), sRef(s), coeffAxial(ca)
}; {} 17
Attributs références
Il est possible de déclarer des attributs qui soient des
références. Ces références ne peuvent être
initialisées à leur déclaration (comme le veut le
cas général).
Les références doivent être initialisées dans la liste
d'initialisation du constructeur, elles ne peuvent
être changées par la suite.

18
Attributs références

Fichier Avion.h

class Avion { Fichier Avion.cpp


Vector3D position;
Vector3D vitesse; Avion::Avion(Aerodynamique
double masse; &a,
Aerodynamique &aero; Propulsion &p)
Propulsion &propu; : aero(a), propu(p)
public: {
Avion(Aerodynamique &a, }
Propulsion &p);
};
19
Attributs objets
Une classe peut avoir des attributs d’une autre classe:
class ClasseA { int main()
int a; {
public:
ClasseA (int aa) { ClasseB bob;
a = aa; return 0;
std::cout << "\n ClasseA"; }
}
}; 'ClasseA' : no appropriate
class ClasseB { default constructor available
int b; Avant d'exécuter quoi que ce
ClasseA objetA;
public: soit dans le constructeur, les
ClasseB () { objets contenus sont
b = 123; construits automatiquement.
objetA = ClasseA(456);
20
};
Attributs objets
Maintenant ça marche :
class ClasseA {
int a;
public:
ClasseA (int aa){ int main()
a = aa; {
std::cout << "\nClasseA"; ClasseB bob;
} return 0;
}; }
class ClasseB {
int b;
ClasseA objetA;
public:
ClasseB ()
: b(123), objetA(456)
21
{} };
Attributs objets
En conclusion :

1) quand un objet est attribut d’un autre objet, son


constructeur est exécuté avant que le corps du constructeur
de la classe conteneur ne le soit;
2) si on n'utilise pas de liste d'initialisation, le code ne
fonctionnera pas (risque d'appels implicites de
constructeurs par défaut ou par copie qui n'existent pas), ou
sera inefficace (construction, puis copie).

22
Attributs de classe «  static »
Jusqu'à présent, nous avons considéré que chaque
objet-instance d'une classe disposait de son propre
exemplaire des attributs dont chaque objet dispose.
Mais il existe également des données qui n'existent
qu'en un seul exemplaire, et dont aucun objet ne
possède une version personnelle : ces données sont
des attributs de classe, on les spécifie par le mot-
clé « static ».

23
Attributs de classe «  static »
Exemples d'utilisation :
• connaître le nombre d'objets d'une classe : on créera
une variable de classe qui s'incrémente dans chaque
constructeur et diminue dans le destructeur ;
• connaître la taille mémoire occupée par les objets
d'une classe : idem ;
• plus généralement, donnée commune à tous les objets
d'une classe.

24
Attributs de classe «  static »
Pour créer un attribut de classe :
1) le déclarer dans la définition de la classe (".h")
avec le mot-clé static ;
2) le définir globalement en dehors de la classe
(".cpp") sans le mot-clé static, mais en faisant
précéder son nom de celui de la classe et (::).

25
Attributs de classe «  static »
Fichier Point.h Fichier Point.cpp

class Point { long Point::MEMORY = 0;


private: int Point::NBR = 0;
double x, y; Point::Point(int n)
int numero; : numero(n), x(0.0), y(0.0) {
static long MEMORY; NBR += 1;
public: MEMORY += sizeof(Point);
static int NBR; }
Point(int n); Point::~Point() {
~Point(); NBR -= 1;
}; MEMORY -= sizeof(Point);
}
26
Attributs de classe «  static »
Les attributs de classe peuvent être déclarés publics,
privés ou protégés. Pour accéder à un attribut de
classe :
• pour un objet de la classe : accès libre, comme un
attribut ordinaire ;
• de l'extérieur : l'accès doit être public, on y accède
soit par l'intermédiaire d'une instance, soit par le
nom de la classe suivi de deux points (::).

27
Attributs de classe «  static »
Fichier Point.h Fichier Main.cpp

class Point #include "Point.h"


{ {
private: Point p1(1);
double x, y; Point *p2 = new Point(2);
int numero; ... = p1.MEMORY; // Interdit,
static long MEMORY; private
public: ... = p1.NBR; // OUI
static int NBR; ... = p2->NBR; // OUI
Point(int n); ... = Point::MEMORY; // Interdit,
~Point(); private
}; ... = Point::NBR; // OUI
} 28
Méthodes de classe «  static »
Comme les attributs de classe, les méthodes de
classe sont des fonctions qui peuvent être
appelées, sans le support d’une instance.
Autrement dit :
• elles ne connaissent pas le pointeur this;
• elles ne peuvent manipuler que les attributs de
classe « static ».

29
Fonctions amies (friend)
Point.h Supposons que l'on veuille écrire une fonction
class Point de comparaison qui soit globale (hors de la
{ classe) :
private: bool comparePoint(const Point& p1,const
double x,y; Point& p2)
int numero; {
public: if ((p1.numero == p2.numero)
Point(); && (p1.x == p2.x)
Point(int num); && (p1.y == p2.y))
~Point(); return true;
} else return false; }

Le problème c’est que les données de la classe sont privées


30
Fonctions amies (friend)
La solution brutale consiste à rendre publics tous les attributs de la
classe Point, mais c'est plus qu'il n'en faut.

Le mot réservé friend constitue une meilleure solution : il permet de


signaler à la classe qu'une fonction particulière aura tous les droits
habituellement réservés aux méthodes de la classe.

31
Fonctions amies (friend)
Fichier Point.h
class Point ATTENTION !
{ Il s'agit bien d'une fonction globale
double x, y; (langage C), pas d'une méthode
int numero; supplémentaire de la classe Point.
public:
Point();
Point(int n);
~Point();
friend int comparePoint(const Point& p1, const Point& p2);
};

32
surcharge des opérateurs
Que se passe-t-il si on veut tester l'égalité entre deux objets d’une
classe quelconque?
ERROR
#include <iostream> binary '==' : 'class Point' does not
#include "Point.h" define this operator or a conversion
int main() to a type acceptable to the
{ predefined operator
Point p1;
Point p2(2.0, 3.0);
if (p1 == p2) L'opérateur de comparaison
std::cout << "Egaux"; n'existe pas pour une classe
else quelconque.
std::cout << "Differents";
};
33
surcharge des opérateurs
En C++, la plupart des opérateurs peuvent être étendus aux objets
pour lesquels un comportement par défaut n'existe pas.

Tous les opérateurs peuvent être ainsi étendus, sauf les


opérateurs ., .*, ::,?: et sizeof.

 Il n'est pas possible de créer des opérateurs à partir de nouveaux


symboles, ni de changer le nombre d'opérandes habituel de l'opérateur
que l'on étend.

34
surcharge des opérateurs
La surcharge conserve également la priorité de l'opérateur original
vis-à-vis des autres opérateurs.
Par contre, la surcharge ne conserve pas :
 l'éventuelle commutativité : si on définit l'opérateur + entre un
réel et un complexe, on n'obtient pas automatiquement l'addition
entre un complexe et un réel ;
 les liens sémantiques avec les autres opérateurs : par exemple, la
surcharge de l'opérateur + est indépendante de celle de ++ et de
celle de +=.
 Il n'est pas possible de définir des valeurs par défaut pour les
paramètres d'une fonction opérateur.

35
surcharge des opérateurs
 Une fonction opérateur est toujours liée à une classe, ce qui fait
qu'il y a toujours deux façons possibles de définir un opérateur :
1.Par une fonction définie dans la classe.
2.Par une fonction globale (souvent amie) possédant au moins un
paramètre qui est un objet ou une référence vers un objet de la classe.

 Une fonction opérateur se définit par le mot-clé operator suivi du


symbole de l'opérateur à surcharger:
operator==
operator<

36
surcharge des opérateurs
Syntaxe
Il faut considérer deux cas (opérateur unaire, opérateur binaire) et
deux façons de les implémenter (méthode, fonction globale amie) :
1.Opérateur unaire « @ » appliqué à un objet de la classe
« MaClasse » retournant TypeRetour :
//V1 : Méthode de la classe « MaClasse »
TypeRetour operator@();
//V2 : fonction globale (amie)
friend TypeRetour operator@(MaClasse&mc);

37
surcharge des opérateurs
Syntaxe
2.Opérateur binaire « @ » appliqué à des objets de la classe
« MaClasse1 » et « MaClasse2 » retournant TypeRetour :
//V1 : Méthode de la classe « MaClasse1 »
TypeRetour operator@(MaClasse2 &mc2);
//V2 : fonction globale (amie)
friend TypeRetour operator@(MaClasse1 &m1,MaClasse2 &m2);

38
surcharge des opérateurs
Regles
1.Si l’operateur ne modifie pas ces arguments alors il est préférable de
le surcharger comme fonction amie (friend)
2.Si l’opérateur modifie ces arguments alors il est préférable de le
surcharger comme fonction membre (méthode).
3.La plus part des opérateur peuvent êtres surcharger soit comme
fonctions membres soit comme fonctions amies à l’exception de :
a.Les opérateurs >> et << doivent être surcharger comme fonctions
amies.
b.Les opérateur =, [], () et -> doivent être surcharger comme fonctions
membres

39
surcharge des opérateurs
Exemple : Classe des nombres Complexe
Ecrire une classe « Complex » pour implémenter les opérations de
base (somme +, Soustraction -, négation –, norme [], conjugué !, …).

40
Héritage
Le mécanisme d'héritage permet de définir une nouvelle classe à
partir de classes existantes (classes de base). Cette nouvelle classe
(classe dérivée) hérite des attributs et des méthodes des classes qui
ont servi à la construire (sauf constructeurs et destructeurs).

Le mécanisme d'héritage permet la réutilisation de code existant


et la non-duplication de code.

41
Héritage
Syntaxe
class Nom_class_derivée: [private|protected|public] class_base1
[,autres_classes_bases] {
//éléments ajoutées aux classes de base
//Redéfinition des méthodes
};
Exemple
#include ‘’A.h’’
#include ‘’B.h’’
class C : public A,private B
{
//définition de la classe C.
};

42
Héritage
Dérivations privées
L'héritage private est celui qui restreint le plus l'accès aux membres
(attributs+méthodes) des classes de base :

43
Héritage
Dérivations privées
Ce type d'héritage s'utilise lorsque la classe dérivée n'est pas un cas
particulier de la classe de base (bien que sa définition s'appuie sur
celle de la classe de base).

44
Héritage
Dérivations protégées
L'héritage protected est moins restrictif que l'héritage privé
L'héritage protected s'emploie dans les mêmes cas que l'héritage
privé.

45
Héritage
Dérivations publiques
C'est l'héritage le moins restrictif et le plus fréquemment utilisé

46
Héritage
Rétablissements des droits d’accès
Il est possible de rétablir les droits d'accès modifiés par la
dérivation pour rétablir les droits d'origine de ces attributs ou
méthodes.
Le rétablissement ne concerne que les membres déclarés public ou
protected dans la classe de base.

47
Héritage
Création et destruction d’objets

48
Héritage
Création et destruction d’objets
Les constructeurs ne sont pas transmis par héritage. Si cela était
possible, on pourrait créer des objets avec un contenu indéfini ou
incomplet.

49
Héritage
Création et destruction d’objets
Dans l'exemple précédent, la bonne façon de faire est d'utiliser la liste
d'initialisation dans un constructeur de B:

class B : public A class B : public A


{ {
int b; Ou int b;
public: public:
B(int n) : A(n) {b=0;} B(int n) : A(n), b(0) {}
}; };

50
Héritage
Création et destruction d’objets
De façon analogue, les destructeurs ne sont pas hérités dans les classes
dérivées. Si cela était possible, seule la partie de l'objet issue de la
classe de base serait affectée par la destruction et non l'objet dans sa
totalité.

51
Héritage
Eléments par défaut
Voici tous les éléments par défaut que le compilateur peut être amené
à
synthétiser automatiquement :

52
Héritage
Convertions d’objets
Par un héritage public, une classe B dérivée de A est considérée
comme une "sorte" de A donc b peut remplacer a
Pour des classes en relation de dérivation publique, le compilateur
effectue certaines conversions implicites :
• objet de la classe dérivée => objet de la classe de base ;
• référence sur un objet de la classe dérivée => référence sur objet
classe de base ;
• pointeur sur un objet de la classe dérivée => pointeur sur objet classe
de base.
Cette conversion implicite n'existe pas si l'héritage est privé ou
protégé.

53
Héritage
Convertions d’objets
class C class D:public C
{ {
}; };
C c,*pc; Le pointeur pc de type *C pointe
D d,*pd; sur un objet de type D
pc=&d; //OK Type statique de*pc: type C
pd=&c;//illégal Type dynamique de *pc= type D
Pour un pointeur ou une référence, il est possible de distinguer :
• le type statique du pointeur/référence : il peut être déterminé à la
compilation, par une analyse statique du code source ;
• le type dynamique : il est déterminé par la valeur courante, et peut
changer encours d'exécution.
54
Héritage
Convertions d’objets
Grâce à ces conversions implicites de pointeurs et de références, tout
objet peut être traité comme un objet plus général. Cela permet de
traiter collectivement un ensemble d'objets de types différents

55
Héritage
Exemple
On veut faire la gestion des étudiants d’une établissement.
Un Etudiant est; par définition; une personne (TD3, Exercice 1). Et il
possède les informations suivantes : CNE, Niveau et Filière.
Ecrire la classe Etudiant.
Ajouter les modificateurs et les accesseurs à la classe Etudiant.
Tester la classe Etudiant.

56
Polymorphisme
Pour indiquer au compilateur que la fonction à appeler doit l'être en
fonction du type dynamique de l'objet, il faut utiliser les méthodes
virtuelles (virtual).

Cette faculté, d'exécuter des fonctions différentes grâce aux


fonctions virtuelles, porte le nom de "polymorphisme".

Une classe qui contient une fonction virtuelle est dite polymorphe.

57
Polymorphisme
Le polymorphisme ne peut être exploité que s'il existe une
hiérarchie de classes, avec des classes dérivées possédant leur propre
version de la fonction.

58
Polymorphisme
La fonction « tracer() » de la classe FigureGeometrique est déclarée
virtuelle. Ainsi, la classe FigureGeometrique devient polymorphe.
Toutes les fonctions « tracer() » des sous-classes héritent aussi de ce
caractère virtuel.

Un constructeur ne peut être déclaré virtuel.

Une fonction statique (de classe) ne peut être virtuelle.

59
Polymorphisme
Une fonction virtuelle est déclarée avec le mot-clé virtual dans la
définition de la classe de base.

class A class B:public A


{ {
virtual void afficher() void afficher()
{ {
cout<<«  classe A»; cout<<«  classe B»;
} }
}; };

60
Polymorphisme
La fonction virtuelle redéfinie doit avoir la même signature et
renvoyer le même type que la version de la classe de base, sinon le
polymorphisme attendu ne se déclenchera pas.

61
Polymorphisme
Quelques remarques

la virtualité se transmet par héritage : si A possède une méthode


virtuelle, que B est une sous-classe (public) de A, que C est une sous-
classe (public) de B, alors C peut redéfinir la méthode de A et
bénéficier du polymorphisme ;

les destructeurs peuvent être virtuels, c'est même obligatoire lorsque


des objets risquent d'être créés dynamiquement par l'intermédiaire d'un
pointeur ou d'une référence vers un type de base.

62
Polymorphisme
Méthodes virtuelles pure

Certaines méthodes sont trop générales pour pouvoir être


implémentées.
C'est le cas par exemple, de la fonction tracer() de la classe
FigureGeometrique.
Une meilleur solution est de déclarer la fonction en question comme
étant virtuelle pure

63
Polymorphisme
Méthodes virtuelles pure

En contrepartie, les classes dérivées ne pourront pas échapper à la


définition de la méthode virtuelle pure et la classe de base ayant une
fonction virtuelle pure ne pourra pas être instanciée.

64
Classes abstraites
Une classe abstraite est une classe qui ne peut être instanciée.

Une classe abstraite est :


Une classe ayant tous ses constructeurs private ou protected
Ou une classe ayant au moins une méthode virtuelle pure.
Ou une classe qui hérite d’une méthode virtuelle pure et ne
l’implémente pas.

65
Classes abstraites
Remarques:
Une classe abstraite ne peut pas servir comme type de paramètre ou
de valeur renvoyée par une fonction (pas de constructeur de copie).

Une classe abstraite ne peut être manipulée qu'au travers de


pointeurs et de références, ce qui autorise le polymorphisme.

66
Templates
Pour éviter de réécrire à chaque fois le même code, il faut utiliser
les modèles de classes (= patrons de classes = templates).

Les templates sont des modèles avec lesquels il est théoriquement


possible de créer un nombre infini de variantes d'une fonction ou d'une
classe à partir d'une seule définition.

67
Modèles de fonctions
Syntaxe:
template <Listes_des_parametres>TypeRet NomFoction(…)

La liste des paramètres peut contenir plusieurs items. Ceux-ci peuvent


être des types (avec le mot-clé class) ou des valeurs d'un type
arithmétique,énumération, pointeur ou référence.

68
Modèles de fonctions
Syntaxe:

Les paramètres de templates peuvent avoir des valeurs par défaut. Les
contraintes qui les concernent sont les mêmes que celles imposées
pour les valeurs par défaut des paramètres de fonctions :

69
Modèles de fonctions
Pour être instanciée par le compilateur, la classe MonType qui sert de
paramètre doit avoir les éléments nécessaires au bon fonctionnement
du modèle de fonction

70
Modèles de classes
Les templates de classes se créent de la même manière que les
templates de fonctions.

template < liste_des_parametres > definition_de_classe

71
Modèles de classes
Une classe de tableaux génériques : // Tableau de 100 entiers
Table<int> tab1(100);
template < class T > class Table tab1[2] = 3;
{ // Tableau de 200 doubles
T *tab; Table<double> tab2(200);
int size; tab2[7] = 10.0;
public:
Table(int n) : size(n) {tab = new T[size];}
~Table() {delete[] tab;}
T& operator[](int i)
{
return tab[i];
}
};
72
Modèles de classes
Une classe de tableaux génériques en type et taille:

template < class T, int size=100 >


// Tableau de 100 entiers
class Table
Table<int,100> tab1;
{
tab1[2] = 3;
T tab[size];
// Tableau de 200 doubles
public:
Table<double,200> tab2;
T& operator[](int i)
tab2[7] = 10.0;
{
if (i>=size) throw("out of bounds");
return tab[i];
}
};

73
Gestion des exceptions
Une solution classique (C, Fortran) consiste à renvoyer un code
d'erreur.
int test(int a)
{
// Renvoie 0 si tout c'est bien passé
// 1 si a est negative
}
Le code de retour doit alors être testé à chaque appel de fonction (pas
toujours réalisé).

74
Gestion des exceptions
Le principe de la gestion des exceptions par C++ est le suivant :

 quand une fonction veut signaler une erreur, elle lance (throw) un
objet erreur ;
lorsque l'utilisateur veut gérer l'erreur, il attrape (catch) l'objet lancé

 une erreur non attrapée conduit à un arrêt du programme.

75
Gestion des exceptions
On lève une exception par l'instruction throw suivie d'une expression
quelconque (entier, double, chaîne de caractères, objet, ...).

76
Gestion des exceptions
Si le programmeur veut gérer son exception, il doit mettre en place :

un bloc réceptif try : il sera en mesure d'attraper une exception


lancée par une des instructions contenues dans le bloc ;

des gestionnaires catch : un par type d'exception que l'on veut


capturer (correspondant au type de l'exception levée par throw).

77
Gestion des exceptions
Exemple:

78
Gestion des exceptions
Exemple: classe exception.
class exception
{
char msg[45];
char fonction[25];
public:
exception();
exception(char*m,char*fnct);
….
};

79
Gestion des exceptions
Exemple: classe Table.
class Table
{
int *T;
int size;
public :
….
int& operator[](int index)
{
if(index>=size) throw(new exception(« index out of bound», ’[]’ ))
return T[index];
}
};

80

Vous aimerez peut-être aussi