Vous êtes sur la page 1sur 14

Chapitre III : Les bases de la programmation Orient Objet (POO) C++

Les classes et les objets

Sommaire
1. 2. 3. 4. 5. 6. 7. 8. CLASSE ET OBJET ...................................................................................................................................................... 1 ACCES AUX MEMBRES ................................................................................................................................................ 3 CONSTRUCTION D'UN OBJET ........................................................................................................................................ 4 DESTRUCTION D'UN OBJET .......................................................................................................................................... 8 MEMBRE CONSTANT ................................................................................................................................................. 8 MEMBRE STATIQUE................................................................................................................................................... 9 LAMITIE............................................................................................................................................................... 10 LA SURCHARGE (REDEFINITION) DES OPERATEURS ............................................................................................................. 1

1. Classe et Objet
1.1. Introductions
Un objet est constitu par l'association d'une certaine quantit de mmoire, organise en champs, et d'un ensemble de fonctions, destines principalement la consultation et la modification des valeurs de ces champs. La dfinition d'un type objet s'appelle une classe. On dit alors que lobjet et un instance de classe.

1.2. Dclaration d'une classe


Pour dclarer une classe, on utilise le mot cl class en respectant la syntaxe suivante Dans les paragraphes suivants nous allons dfinir les lments que peuvent contenir une classe, mais aussi nous donnerons les rgles qui rgissent lutilisation des classes et linstanciation dobjet. Remarque : Le mot cl type_hritage permet de dfinir un type d'hritage. Il existe trois types d'hritage possibles : public, protected ou private. Le point virgule situ la fin du bloc de dfinition de la classe est obligatoire. class NomClasse [ : type_hritage NomClasseHrite] { [ public: // dfinition des champs et mthodes publics ] [ NomClasse(); ] // constructeur [ ~NomClasse(); ] // Destructeur [ protected: // dfinition des champs et mthodes protgs ] [ private: // dfinition des champs et mthodes prives ] };

Exemple On veut construire une classe qui manipule des points dfinis par une abscisse et une ordonne (de type entier). La 1re version de cette classe permet dafficher et de dplacer un point. Ici, les membres nomms x et y sont class Point { privs, tandis que les fonctions private : // il faut protg les donnes membres nommes afficher et deplacer membre par un private int x, y; sont publiques. En ce qui concerne la dfinition des public: fonctions membres dune classe, elle se void afficher() fait exactement de la mme manire { que celle des fonctions en C sagisse de cout << "L'abscisse vaut " << x << endl; fonctions. cout << "L'ordonne vaut " << y << endl; { Quil sagisse de fonctions publiques void deplacer(int dx, int dy) ou prives, ces fonctions membres ont { accs lensemble des membres x = dx; (publics ou privs) de la classe. y = dy;
}

1.3. Dfinition d'une classe


1.3.1. Dfinition spare et oprateur de rsolution de porte Tous les membres d'une classe doivent tre au moins dclars l'intrieur du bloc class NomClasse {...}; qui constitue la dclaration de la classe. Cependant, dans le cas des fonctions, aussi class Point { Private : bien publiques que prives, on peut se limiter int x, y; n'crire que leur en-tte (prototype) l'intrieur de la classe et dfinir le corps ailleurs, dans le public : void afficher() mme fichier ou bien dans un autre fichier. }; Loprateur de rsolution de port : : sert report la dfinition de la fonction membre void Point::affiche() hors de sa classe. Deux manires peuvent tre { exploites avec cette dfinition, la premire cout << "L'abscisse vaut " << x << endl; cout << "L'ordonne vaut " << y << endl; -montre ci-contre consiste en la dfinition de } la classe et les dclarations de ces mthodes dans un mme fichier. 1.3.2. Fichier d'en-tte et fichier d'implmentation Pour profiter pleinement de la programmation orient objet ; nous devrions sparer la dfinition des classes, les dclarations de fonctions et linstanciation des objets dans le programm e principal. Pour un simple programme, nous aurions besoin de trois fichiers : Point.h : On dclare dans ce fichier la classe Point, avec seulement les enttes des mthodes. Point.cpp: Il contient la dfinition de chaque fonction avec lutilisation de loprateur : :. Main.cpp : Une fois inclus le fichier d'en-tte Point.h, on peut dfinir 3 points A, B et C. A, B et C sont 3 objets qui sont des instances de la classe Point.
Point.h class Point { public : int x, y; public : void afficher(); void deplacer(int dx, int dy); }; Point.cpp #include "Point.h" void Point::afficher() { cout<< "L'abscisse :" << x<< endl; cout<< "L'ordonne :" << y<< endl; { void Point::deplacer(int dx, int dy) { x = dx; y = dy; }

Main.cpp #include <iostream> using namespace std; #include "Point.h" int main() { cout << "point statique :" Point a; *pt; system("PAUSE"); return EXIT_SUCCESS; }

<<

partir de maintenant, nous allons dfinir et dclarer chaque classe dans deux fichier nomclasse.h et nomclasse.cpp .

2. Accs aux membres


2.1. Cration et utilisation d'un objet
Une classe dfinit un type, qui peut tre utilis comme tout autre type disponible. On note la notation pointe (.) utilise pour appliquer une mthode sur un objet (objet statique). Cette notation se transforme en notation flche (->) si on dispose dun pointeur sur objet (objet dynamique). Au niveau mmoire, chaque dfinition dun nouvel article entrane la rservation dun espace mmoire permettant de reprsenter tous les attributs de la classe Point (labscisse, lordonne). Chaque point possde donc sa propre copie dattributs, 2.1.1. Dans le cas statique La cration statique des objets se fait selon la syntaxe suivante : Point a, b; La variable a correspond un objet de type Point que lon peut utiliser pour accder aux donnes et fonction membres. a.x = 0; // un accs au membre x du point a (si x est public) a.afficher(); // un appel de la fonction afficher de l'objet a Les objets crs de faon statique sont automatiquement dtruits ds que le programme quitte la porte o ils ont t crs, en gnral la sortie du bloc. Le programmeur na donc pas besoin de les dtruire. 2.1.2. Dans le cas dynamique Pour la cration dynamique dun objet, il convient de respecter les tapes suivantes : Dfinir un pointeur vers la classe ; Utiliser loprateur new ; Dtruire lobjet aprs son utilisation. Point * pt ; pt = new Point; Loprateur new cre un objet de type Animal et renvoie ladresse de lobjet cr, ce qui permet dinitialiser le pointeur pt. Ce pointeur peut ensuite tre utilis pour accder aux donnes et fonctions membres de la classe. pt->x = 0; // un accs au membre x du point point par pt pt->deplacer(2,3) // un appel de la fonction affiche de l'objet point par pt Dans le cas de la cration dynamique, il faut obligatoirement dtruire les objets aprs les avoir utiliss. Pour cela, C++ fournit loprateur delete qui permet de dtruire lobjet rfrenc par un pointeur. delete pt ; 2.1.3. Autorfrence (Pointeur this) Il arrive que dans une fonction membre d'un objet on doive faire rfrence l'objet courant (en entier) travers lequel on a appel la fonction. Il faut savoir que dans une fonction membre on dispose du mot-cl this qui reprsente un pointeur vers l'objet en question. La fonction afficher peur alors scrire de la manire suivant, qui na pas un grand intrt. void afficher() { cout << '(' << this->x << ',' << this->y << ')'; } Un autre exemple plus utile est la fonction compare qui vrifier si deux point sont gaux ou nom, le deuxime point est pass en paramtre. bool compare (point pt) { return (this -> x == pt.x) && (this -> y == pt.y) } bool compare (Point *pt) { return pt->x == x && pt->y == y; } bool compare (Point *pt) { return pt == this; }

2.2. Accesseur et mutateur


Parmi les mthodes dune classe, on distingue deux catgories : les mthodes qui modifient ltat de lobjet, mthodes appeles mutateurs (modificateurs), et les mthodes qui ne modifient pas ltat de lobjet mais qui y accdent en lecture. Ces dernires sont appeles accesseurs. Il est important de dterminer dans quelle catgorie se situe une mthode car son prototype en dpend. Les accesseurs sont des mthodes dclares constantes (il y a un const aprs la liste des arguments). Les modificateurs ont frquemment un nom tel que Set() et les accesseurs Get(). Ces mthodes spcifiques permettent daccder ou de modifier les valeurs des donnes membres prives. Ces mthode seront toujours publics.
Point.h class Point { private: int x, y; public : void afficher(); void deplacer(int dx, int dy) ; void setX(int x); void setY(int y); int getX(); int getY(); };

Point.cpp void Point::setX(int x) { this->x = x; } void Point::setY(int y) { this->y = y;} int Point::getX() return x; } int Point::getY() return y; } { {

La mthode void setX(int x) est un mutateur qui permet de modifier la donne membre prive x. Idem pour void setY(int y) avec la donne membre prive y. Les mthodes int getX() et int getY() sont des accesseurs qui permettent d'accder aux valeurs respectives des donnes membres prives x et y. Aussi la fonction afficher et un accesseur, cette dernire naffecte pas ltat de l objet contrairement la fonction deplacer qui change ltat de lobjet.

3. Construction d'un objet


3.1. Dfinition dun constructeur
Un constructeur d'une classe est une fonction membre spciale qui : A le mme nom que la classe, N'indique pas de type de retour (mme pas un void), Ne contient pas d'instruction return. Lors de la cration dun objet en statique ou en dynamique, le C++ alloue la zone mmoire n cessaire lobjet, puis appel une fonction membre spciale de la classe nomme constructeur. Lappel au constructeur dune classe se fait la cration de lobjet, il est partie intgrante du cycle de vie dun objet. Il sagit donc de la premire mthode excute pour un objet et elle constitue de ce fait lendroit idal pour initialiser les donnes membres dun objet. Une classe peut possder plusieurs constructeurs, qui doivent alors avoir des signatures diffrentes :
class Point { public: N1 Point(int abs, int ord) { x = abs; y = ord; } N2 Point(int abs) { x = abs; y = 0; } N3 Point() { x = y = 0; } ... autres fonctions membres ... };

N4

Point(int abs = 0, int ord = 0){ x = abs; y = ord; }

L'emploi de paramtres avec des valeurs par dfaut permet de grouper des constructeurs. Dans la classe prcdente les trois manires dcrire le constructeur (N 1, 2, 3) peuvent tre remplaces par le constructeur de droite (N3=).

3.2. Appel dun constructeur


Un constructeur ne peut pas tre appel autrement que lors dune initialisation. Cependant, il peut ltre de diffrentes faons. Par exemple, sil existe un constructeur qui nadmet quun seul paramtre, ou plusieurs mais tel que tous les arguments sauf le premier ont une valeur par dfaut, on peut lappeler en crivant le signe gal suivi du paramtre. 3.3.1. Dans le cas statique Un constructeur est toujours appel lorsqu'un objet est cre, soit explicitement, soit implicitement. Les appels explicites peuvent tre crits sous deux formes : Point a(3, 4); Point b = Point(5, 6); Dans cette dernier expression, le signe = nest pas une affect ation mais une initialisation du point b en affectant en rangeant dans b.x et b.y les valeurs 5 et 6. Dans le cas d'un constructeur avec un seul paramtre, on peut aussi adopter une forme qui rappelle l'initialisation des variables de types primitifs : Point e = 7; // quivaut : Point e = Point(7) 3.3.2. Dans le cas dynamique Un objet allou dynamiquement est lui aussi toujours initialis, au moins implicitement. Dans il doit, tre initialis explicitement : Point *pt1, *pt2 ; // dans cette phase il ny a pas de construction dobjet tant quil ny a pas appel au constructeur. pt1 = new Point ; // appel implicite du constructeur par dfaut pt2 = new Point(1, 2); // appel explicite du constructeur N1.

3.3. Constructeur par dfaut (ou sans argument)


Ce constructeur est une fonction membre sans argument qui est utilise par dfaut chaque fois que lon cre un objet en statique ou en dynamique et que la classe ne possde pas dautre. A noter qu'il peut s'agir d'un constructeur sans paramtres, ou d'un constructeur dont les paramtres ont des valeurs par dfaut. Le constructeur N 3 est un constructeur par dfaut. Si le programmeur crit une classe sans aucun constructeur, alors le compilateur synthtise un constructeur par dfaut. Le constructeur par dfaut est ncessaire pour la cration de tableau dobjet. Point x; // quivaut : Point x = Point() Point t[10]; // produit 10 appels de Point() Point *p = new Point; // quivaut : p = new Point() Point *q = new Point[10]; // produit 10 appels de Point()

3.4. List dinitialisation dun constructeur


La plupart des constructeurs ne font quinitialiser les donnes membres des objets, cest pourquoi C++ prvoit une formule syntaxique spciale pour la dfinition du constructeur. Les listes dinitialisation. Loprateur : introduit la liste dinitialisation juste aprs la liste des paramtres du constructeur. Pour chaque affectation le nom de la donne membre est suivi de sa valeur din itialisation entre parenthses. De cette faon le constructeur N de notre exemple devient
Point(int abs, int ord) : x(abs), y(ord) { }

Et le constructeur N4 devient
Point(int abs = 0, int ord = 0) : x(abs), y(ord) { }

Reste toujours que ce dernier constructeur remplace les autres constructeurs de la classe Point.

3.5. Constructeur de recopie


Le but de ce constructeur est d'initialiser un objet lors de son instanciation partir d'un autre objet appartenant la mme classe. Il doit tre obligatoirement de lune de ces deux formes : NomClasse (NomClasse &) NomClasse (const NomClasse &) Remarque : Le passage par rfrence : C++ oblige un passage par rfrence dans le cas d'une construction par recopie. Ceci vient du fait qu'il faut rellement utiliser l'objet lui-mme, et non une copie. La prsence d'un "const" : Est simplement une protection de l'objet recopier. En effet, lors de cette recopie, nous faisons appel l'objet lui-mme, et le const ne fait que protg lobjet de toute modification non prvu. Le constructeur de recopie doit tre appel lors de la dclaration de lobjet NomClasse c1; // constructeur par dfaut pour lobjet c1 NomClasse c2 = c1; // appel du constructeur de copi,e quivaut NomClasse c2(c1); Si le programmeur n'a pas dfini de constructeur de copie pour une classe, le compilateur synthtise un constructeur par copie consistant en la recopie de chaque membre d'un objet dans le membre correspondant de l'autre objet. Exemple : class Liste private : int taille; float *adr; public: liste(int t) // Constructeur { taille = t; adr = new float[taille]; cout<<"Construction"; cout<<" Adresse de l'objet:" <<this; cout<<" Adresse de liste:" << adr <<endl; } void affiche() { cout<<" Adresse de l'objet:"<<this<<endl; cout<<" Adresse de liste:"<< adr <<endl; } Dans main () : Liste a(3); Liste b = a; b.affiche() ;
Execution : Construction Adresse de l'objet:0x22ff40 Adresse de liste:0x1021060 Adresse de l'objet:0x22ff38 Adresse de liste:0x1021060

Dans ce cas les deux objets a et b possde une donne qui pointe vers le mme tableau. Si nous ajoutant dans la class List ce code qui dfini le constructeur de recopie. liste(liste &v) // Constructeur de recopie { taille = v.taille; adr = new float[taille]; // allocation de la mmoire for(int i=0;i<taille;i++) adr[i] = v.adr[i]; // recopie des valeurs cout<<"\nConstructeur par recopie"; cout<<" Adresse de l'objet:"<<this; cout<<" Adresse de liste:"<<adr<<"\n"; }
6

Nous aurons les rsultats suivant : Dans main () : Liste a(3); Liste b(a);

Execution : Construction Adresse de l'objet:0x22ff30 Adresse de liste:0xce1060 Constructeur par recopie Adresse de l'objet:0x22ff20 Adresse de liste:0xce1078

Dans ce cas nous avons recopi les valeurs contenues dans le tableau de a vers un nouveau tableau allou pour b.
a.adr b.adr a
a b a.adr b.adr

Cas sans constructeur de recopie

avec constructeur de recopie

3.6. Construction des objets membres


Il est tout fait possible quune classe possde un membre donne lui-mme de type classe. Par exemple, nous dfinissons : class point { int x, y ; public : Point (int, int) ; deplacer (int, int) ; }; Nous pouvons dfinir class Segment { Point origine, extremite; int epaisseur; public: Segment(int, int, int) ; Affiche (int, int, int) ; }; Si nous dclarons: Segment S ; Lobjet S possde deux donnes membres privs origine et extremite, de type point. Lobjet S peut accder classiquement la mthode affiche par S.affiche(). Par contre, il ne pourra pas accder la mthode deplacer du membre origine car il est priv. Si origine tait public, on pourrait accder ses mthodes par c.centre.Point () ou c.centre.deplacer (). Dans cet exemple, l'initialisation d'un objet segment ncessite l'initialisation de ces objets membres, il faut imprativement dclarer un constructeur de segment qui permettra de spcifier les paramtres du constructeur des points origine et extremite. class Segment { Point origine, extremite; int epaisseur; public: Segment(int ox, int oy, int ex, int ey, int ep) : origine(ox, oy), extremite(ex, ey) { epaisseur = ep; } ... }; Les arguments passs au constructeur des points doivent figurer dans la liste des arguments du constructeur de segment, Les constructeurs seront appels dans lordre suivant : point, segment. Sil existe des destructeurs, ils seront appels dans lordre inverse.
7

4. Destruction d'un objet


De la mme manire qu'il y a des choses faire pour initialiser un objet qui commence exister, il y a des dispositions prendre lorsqu'un objet va disparaitre. Un destructeur est une fonction membre spciale. Il a le mme nom que la classe, prcd du caractre ~. Il n'a pas de paramtre, ni de type de retour. Il y a donc au plus un destructeur par classe. Le destructeur d'une classe est appel lorsqu'un objet de la classe est dtruit, juste avant que la mmoire occupe par l'objet soit rcupre par le systme. Par exemple, voici le destructeur qu'il faut ajouter la classe Liste. Sans ce destructeur, la destruction d'une liste n'entrainerait pas la libration de l'espace allou pour le tableau adr. Liste :: Liste() { delete adr; }

5. Membre constant
5.1. Donnes membres constantes
Une donne membre d'une classe peut tre qualifie const. Il est alors obligatoire de l'initialiser lors de la construction d'un objet, et sa valeur ne pourra par la suite plus tre modifie. Dans lexemple de la classe segment, dont voici une nouvelle version, dans laquelle chaque objet reoit, lors de sa cration, un numro de srie qui ne doit plus changer au cours de la vie de l'objet : class Segment { Point origine, extremite; int epaisseur; const int numeroDeSerie; public: Segment(int x1, int y1, int x2, int y2, int ep, int num); }; Comme numeroDeSerie est une constante alors la modification de cette constante dans le corps du constructeur va gnrer une erreur, la seul solution est de linitialise dans la liste dinitialisation Segment::Segment(int x1, int y1, int x2, int y2, int ep, int num) : origine(x1, y1), extremite(x2, y2), numeroDeSerie(num) { Correcte Incorrecte epaisseur = ep; numeroDeSerie = num; //Erreur : modification de constante }

5.2. Mthode membres constantes


Le mot const plac la fin de l'en-tte d'une fonction membre indique que l'tat de l'objet travers lequel la fonction est appele n'est pas chang du fait de l'appel. C'est une manire de dclarer qu'il s'agit d'une fonction de consultation de l'objet, non d'une fonction de modification : class Point { ... void placer(int a, int b); // modifie l'objet float distance(Point p) const; // ne modifie pas l'objet ... }; float Point::distance(Point p) const { int dx = x - p.x; int dy = y - p.y; return sqrt(dx * dx + dy * dy); }

Dans cette classe, nous avons spcifi que la fonction distance tait utilisable pour un point constant . En revanche, la fonction placer, qui na pas fait lobjet dune dclaration const ne le sera pas. Ainsi, avec ces dclarations : Point a ; const Point b ; Les instructions suivantes seront correctes : a.placer (2,3) ; float c = b.distance (a) ; c = a.distance (b) ; Par contre, celle-ci sera rejete par le compilateur : b.placer (3,5) ; // incorrecte ; b est constant, alors que placer ne lest pas La mme remarque sapplique un objet reu en argument : void uneFonction(const Point a) { Point b; double d = a.distance(b); ... } La qualification const de la fonction distance est indispensable pour que l'expression prcdente soit accepte par le compilateur. C'est elle seule, en effet, qui garantit que le point a, contraint rester constant, ne sera pas modifi par l'appel de distance. Si la fonction distance nest pas constante on aura alors une erreur de compilation.

6. Membre statique
Chaque objet d'une classe possde son propre exemplaire de chaque membre ordinaire de la classe : Pour les donnes membres, cela signifie quune nouvelle mmoire est alloue pour chaque objet; Pour les fonctions membres, elles ne peuvent tre appeles qu'en association avec un objet. A l'oppos de cela, les membres statiques, signals par la qualification static, sont partags par tous les objets de la classe. De chacun il n'existe qu'un seul exemplaire par classe, quel que soit le nombre d'objets de la classe.

6.1. Donnes membres statiques


Dans la version suivante de la classe Point, il nexiste quun seul exemplaire du membre nbrPoints pour tous les objets instancis de cette classe. class Point { int x, y; public: static int nbrPoints; // dclaration dune variable statique Point(int a, int b) { x = a; y = b; nbrPoints++; } }; Aprs avoir dclar nbrPoints, Il faut encore la crer et linitialiser. Cela se fait par cette formule qui ressemble une dfinition de variable, crite dans la porte globale (avec loprateur de rsolution de port), mme s'il s'agit de membres privs : int Point::nbrPoints = 0; L'accs un membre statique peut se faire travers un objet : Point a ; cout << a. nbrPoints << endl; Ou travers la classe dinstanciation: cout << Point:: nbrPoints << endl;
9

6.2. Mthode membres statiques


Une fonction membre statique n'est pas attache un objet, elle ne peut rfrencer que les fonctions et les membres statiques. Par exemple, voici la classe Point prcdente, dans laquelle le membre nombreDePoints a t rendu priv pour en empcher toute modification intempestive. Il faut donc fournir une fonction pour en consulter la valeur, nous l'avons appele combien : class Point { int x, y; public: static int nbrPoints; static int combien() { return nbrPoints; } Point(int a, int b) { x = a; y = b; nbrPoints++; } }; int Point::nbrPoints = 0; Par la mme logique que pour les membres statique, en utilise une fonction statique Point a; cout << a.combien() <<endl; cout << Point::combien() ;

7. Lamiti
Le mot cl friend est utilis pour permettre des fonctions ou des classes daccder aux membres privs et protgs dune autre classe. Cette technique a donc pour objectif de lever linterdiction daccs lie aux tiquettes private et protected.

7.1.

Fonction amies

Une fonction amie doit tre dclare ou dfinie dans la classe qui accorde le droit d'accs, prcde du mot rserv friend. Cette dclaration doit tre crite indiffremment parmi les membres publics ou parmi les membres privs :

Exemple : class Tableau { int *tab, nbr; friend void afficher(const Tableau &); public: Tableau(int nbrElements); ... };

void afficher(const Tableau &t) { cout << [; for (int i = 0; i < t.nbr; i++) cout << ' ' << t.tab[i]; cout << "]" ; }

10

7.2.

Mthode amies

Il sagit un peu dun cas particulier de la situation prcdente. En fait, il suffit simplement de prciser, dans la dclaration damiti, la classe laquelle appartient la fonction concerne, laide de loprateur de rsolution de porte (::).

Exemple : class Tableau; class Vecteur { ... public: void afficher(const Tableau &); ... }; class Tableau { int *tab, nbr; public: friend void Vecteur::afficher(const Tableau&); ... };

void Fenetre::afficher(const Tableau &t) { cout << "["; for (int i = 0; i < t.nbr; i++) cout << ' ' << t.tab[i]; cout << "]" ; }

7.3.

Classe Amies

Lorsquon souhaite que tous les membres dune classe puissent accder aux parties prives dune autre classe, on peut dclarer amie une classe entire : class A; // dclaration class B { // parties prives... public : friend A; // ... }; class A { // ... }; Les membres de la classe A peuvent tous modifier des instances de B (mme les parties prives). Noter la dclaration de A avant celle de exemple, obligatoire sinon on obtient une erreur de compilation comme quoi B est indfinie. Pour lviter, on peut ventuellement changer lordre de dfinition, mais il suffit en fait de prciser le slecteur class derrire friend tel : friend class A pour remplacer friend A.

11

8. La surcharge (redfinition) des oprateurs


Le langage C++ permet de surcharger les oprateurs pour les classes dfinies par lutilisateur, en utilisant une syntaxe particulire semblable la syntaxe utilise pour dfinir des fonctions membres ordinaires. Exemple : Pour une classe Vecteur, loprateur + ne fonctionnera pas correctement donc il faut le surcharger pour quil puisse additionner deux vecteurs : vecteur v1, v2, v3; v3 = v2 + v1;

8.1. Oprateurs simples


La plupart de ces oprateurs peuvent tre surchargs : + , - , * , / , % , = = , ~ , < , > , ! , & , ^ , [ ] Syntaxe : Type_de_retour operator Signe_de_loprateur (Liste des arguments) { ;} Exemple :
class Point{ int x; int y; public : Point( ) ; Point(int a, int b){ x = a ; y = b; } Point operator + (const Point & a) ; Point operator - (const Point & a) ; int operator == (const Point & p) ; void Affiche( ) { cout << "coordonnees :" << x << " " << y <<endl;} }; Point Point :: operator + (const Point & a) { Point p; p.x = x + a.x; p.y = y + a.y; return p ; } int Point :: operator == (const Point & p) { if( x == p.x && y == p.y ) return 1 ; else return 0 ; }

Nous remarquons dans cette exemple le "const Point & a ". Ceci signifie que l'on passe un point en paramtre (l'autre point de l'addition est en fait lobjet courant). Ce dernier est transmis par rfrence, afin d'viter une recopie. Le "const" est optionnel mais permet d'viter de modifier les paramtres.

8.2. Surcharge d'un oprateur par une fonction membre


Lexemple prcdent montre la redfinition de loprateur + et == par des fonctions membres, le premier oprande tant lobjet courant, voici un exemple de programme montrant la redfinition et lutilisation de notre oprateur daddition de points :
main() { point a(1,2) ; a.affiche() ; point b(2,5) ; b.affiche() ; point c ; c = a+b ; c.affiche() ; c = a+b+c ; c.affiche() ; }

Coordonnee : 1 Coordonnee : 2 Coordonnee : 3 Coordonnee : 6

2 5 7 14

Une expression telle que a + b est en fait interprte par le compilateur comme lappel : operator + (a, b) Alors on peut crire c = operator + (a, b) au lieu de c = a + b.
12

8.3. Surcharge d'un oprateur par une fonction amie


Le prototype de notre fonction operator + sera : point operator + (point, point) ; Ses deux arguments correspondront aux oprandes de loprateur + lorsquil sera appliqu des valeurs de type point.
class point{ int x, y ; public : point (int abs=0, int ord=0) { x=abs ; y=ord ;} // constructeur friend point operator+ (point, point) ; void affiche () { cout << "coordonnees : " << x << " " << y << endl ;} } ; point operator + (point a, point b) { point p ; p.x = a.x + b.x ; p.y = a.y + b.y ; return p ; }

Voici un programme montrant la redfinition et lutilisation de notre + :


main() { point a(1,2) ; a.affiche() ; point b(2,5) ; b.affiche() ; point c ; c = a+b ; c.affiche() ; c = a+b+c ; c.affiche() ; }

Une expression telle que a + b est en fait interprte par le compilateur comme lappel : operator + (a, b) Bien que cela ne prsente gure dintrt, nous pourrions crire : c = operator + (a, b) au lieu de c = a + b. et (a + b) + c operator + (operator + (a, b), c)

8.4. Injection et extraction de donnes dans les flux Cas de l'oprateur <<
Afin de remplacer la fonction affiche membre de la classe Point, nous pouvons surcharger l'oprateur de sortie << pour afficher sur lcran les coordonnes dun point. Nous allons utiliser la fonction amie ostream& operator<< qui est membre de la classe ostream qui dfini les flux de sortie. class Point { ... friend ostream& operator<<(ostream&, const Point); }; ostream& operator<<(ostream &o, const Point p) { return o << '(' << p.x << ',' << p.y << ')'; } Avec cette surcharge de << nos points s'crivent sur un flux de sortie comme les donnes primitives : Point p; ... le point trouv est (2,5) cout << "le point trouv est : " << p << "\n";

13