Vous êtes sur la page 1sur 25

Chapitre 7

Chapitre 7
Surcharge des opérateurs
g p
Dr. LAHBIB Younes
Dr. LAHBIB Younes

1
Plan 
Plan
• Fonctions et classes amies
• Surcharge des opérateurs
Surcharge des opérateurs

2
FONCTIONS ET CLASSES AMIES

3
Fonctions et classes amies

• Dans certains cas, on veut que des fonctions externes ou 
des méthodes d’autres classes puissent accéder 
directement aux membres privés d’une classe. 

⇒ Solution : déclarer des fonctions et des classes amies 
: déclarer des fonctions et des classes amies
avec le qualificateur     friend

4
Fonctions et classes amies (syntaxe)

class A

{ private:
…….
public : class
l B
…… {
friend type_retour nom_fct
(
(…….);
) ……
friend class B; public:
};
…….//
// accès direct aux membres
//privés de A
type_retour nom_fct (…….)
{
……………//accès direct aux membres
// privés de la classe A
} };

5
Exemple 1 (fonction amie)
class point
{
p
private:
int abs,ord;
public:
point(int =0,int
0,int =0);
0);
~point(){ }
. . . .
friend void afficher(point p);
afficher(point p); //fonction externe amie
//fonction externe amie
};

void
id afficher(point p)
ffi h ( i t )
{
cout<<“(″<<p.abs <<“,″<<p.ord <<“)″ ;

⇒ La notion d’objet courant (this) n’existe pas dans les méthodes amies. 
⇒ L’objet sur lequel on va agir doit être passé comme paramètre
L’ bj t l l i d it êt é èt

6
Exemple 2 (classe amie)
class liste 
class liste
class nœud  {
{ private : 
private : 
i t nœud * tete;
int val;  public:
nœud * suiv; liste();
public: ~liste();
nœud (int, nœud * s =NULL); …….
~nœud();
nœud(); void afficher()
……. { nœud * parc = tete;
friend class liste; // classe amie while (parc !
(parc !=NULL)
NULL)
}; {
cout<<parc‐>val ;
parc = parc‐>suiv;
i
}
}
};
7
SURCHARGE DES OPÉRATEURS

8
Surcharge d’opérateurs

• L’une des techniques puissantes du langage C++ est la possibilité de surcharger 
les opérateurs pour les classes définies par l’utilisateur. 
p p p

• Cette surcharge peut être réalisée à l’intérieur de la classe (fonction membre) 
ou à l’extérieur de la classe (fonction amie) sauf pour les opérateurs :
à l’ é d l l (f ) f l é
ƒ = ( ) → [ ] qui doivent être surdéfinis en tant que fonction membre. 
ƒ <<   >> qui doivent être surchargés en tant que fonction amie
q g q

• Certains opérateurs ne peuvent pas être surchargés  :: . ? :

9
• Syntaxe générale de surcharge :
_
Type_retour operator symbole(paramètres)

• Une fois les opérateurs sont surchargés, ils sont utilisés dans leur format 
standard.
t d d

• ppe des opé ateu s : se fait selon l’une des deux manières suivantes


Appel des opérateurs se a se o u e des deu a è es su a es :
A symbole B
ou 
A.operator symbole(B)

Appel qui ne peut être valable que si la 
surcharge est réalisée en tant que membre

10
I. Surcharge de l’opérateur +
• Nous considérons dans ce qui suit l’exemple de la classe Complexe définie 
comme suit :

class Complexe
{
private :
float re, im ;
public :
Complexe (float, float) ;
~ Complexe() {}
. . . . . . . . .
};

11
I.1. Surcharge en tant que fonction membre
class Complexe
{ private :
float re, im ;
public :
Complexe (float, float);
~ Complexe() {}
Complexe operator + (Complexe); //1ère surcharge
Complexe operator + (float); //2ème surcharge
};

Complexe Complexe::operator +(Complexe c)


{
return
t (C
(Complexe(re
l ( + c.re, i
im + c.im));
i ))
}

Complexe Complexe::operator +(float x)


{
return (Complexe(re + x, im));
}

12
void main()
{
Complexe c1(1,2), c2(5,4), c3(0,0);
C3= c1 + c2 ; //appel de la 1ère surcharge
//⇔ c3 = c1.operator+(c2);

C3= c1 + 20 //appel de la 2ème surcharge


//⇔ c3 = c1.operator+(20);

C3= 20 + c1 //erreur car l’opérande gauche doit être


//toujours un membre de la classe selon ces
//surcharges
// g (
(en tant q
que fonctions membres))
}

13
I.2. Surcharge en tant que fonction externe amie
class Complexe
{ private :
float re, im ;
public :
Complexe (float, float);
~ Complexe() {}
Complexe operator + (Complexe); //1ère surcharge
Complexe operator + (float); //2ème surcharge
friend Complexe operator + (float, Complexe);//3ème surcharge
};

Complexe operator + (float x, Complexe c) //3ème Surcharge


{
return (Complexe (x+c.re, c.im));
}
C
Cette surcharge permet d’assurer la 
h d’ l
commutativité de l’opérateur +

14
void main()
{
Complexe c1(2,3), c2(7, 8), c3(10, 2), c(0, 0);

c4 = 10 + c1; //3ème surcharge


/* fonction amie, ne peut pas être écrite selon la
manière
iè c4 = 10.operator+ (c1) car 10 n’est pas un
objet de la classe*/
}

15
II. Surcharge de l’opérateur =

• En cas d’absence de surcharge de l’opérateur = dans une classe 
d
donnée, le compilateur utilise un opérateur d’affectation par 
é l il t tili é t d’ ff t ti
défaut qui fait une affectation des attributs des objets un par un. 

Problème dans le cas de classes définies par des pointeurs (cas 
d’allocation
d allocation dynamique). 
dynamique)

Solution : une sur‐définition de cet opérateur est obligatoire dans 
: une sur définition de cet opérateur est obligatoire dans
ces cas.

16
• Syntaxe de surcharge de = 

nom_classe& operator = (const nom_classe & nom_objet)


{ On doit faire ce test pour ne pas 
if (this != & nom_objet) écraser la variable en cas d’égalité
{
…………//code du destructeur Pointeur sur l’objet courant
……… //code du constructur par recopie
}
return (*this) ;
}
Retour de l’objet courant pour permettre 
les affectations multiples
les affectations multiples

Remarque

this : pointeur sur l’objet courant. 
attribut ⇔ this → attribut : Accès aux attributs de l’objet courant
⇔ (*this).attribut
17
Exemple 1
class Complexe void main()
{ {
private : Complexe
p c1(2,
( , 3),
),
float re, im ; c2(4, 5),
public : c3(0,0) ;
Complexe (float, float); c3 = c2 ;
~ Complexe() {} c3 = c2 = c1 ;
Complexe& operator = (const
Complexe& c);
}
}; }
Complexe& Complexe operator = (const Retour de l’objet c2 qui est 
Complexe& c) affecté ensuite dans c3
{
if (this != &c)
{ Retour de type référence sur complexe, pour 
yp p ,p
re = c.re; pouvoir gérer des affectations multiples
im =c.im;
}
return (*this);
} 18
class pile
{ Exemple 2
private :
int * tab, taille, tete ;
public :
pile(int =10)
10) ;
~pile() ;
pile(const pile&) ;
pile& operator
p p = (
(const p
pile &)
) ;
};
pile& pile ::operator = (const pile & p)
{
if (this != &p)
{//code du destr.
delete[] tab;
taille = p.taille;
p taille;
//Code du const.par recopie
tete = p.tete ;
tab = new int [taille];

for(int i=0;i<= tete; i++)


tab[i] = p.tab[i];
}
return (*this);
} 19
III. Surcharge de l’opérateur [ ]
• Cet opérateur est défini généralement pour les tableaux afin d’accéder à leurs 
éléments. 

• Il peut être surchargé selon les besoins dans les classes définies par le programmeur. 

Syntaxe :

class nom_classe
{
private :
…….
public :
……..
type_retour operator[] (int) ;
……………
};

20
Exemple
class vecteur
{ void main( )
private : {
float * tab ; vecteur v(3);
int taille ; …….
public : cout<<v[10];
vecteur (
(int)
) ;
~vecteur() ; fl t x = v[1];
float [1]
…………. v[2] = 20;
float& operator[] (int) ; }
}
}; cette instruction est 
possible grâce au 
float& vecteur :: operator[] (int i)
retour par référence
{
if (i>=0)&&(i<taille)
return tab[i];
else
{ cout<<”erreur”;
t ” ”
return tab[0];
}
}

21
IV. Surcharge de l’opérateur <<

• Cette surcharge ne peut être réalisée qu’en tant que fonction externe amie étant 
donnée que l’opérande gauche est toujours un objet de type ostream. 

• Cette surcharge doit retourner un objet de type ostream afin de permettre un affichage 
multiple sur une même ligne. 

Syntaxe :

class nom_classe
nom classe
{
private :
…….
public :
friend ostream& operator << (ostream&, const nom_classe &)
};

22
Exemple
class Complexe
{
private :
float re, im ;
public :
Complexe (float, float);
~ Complexe()
p {}
friend ostream& operator << (ostream&, const Complexe &)
};

ostream& operator << (ostream& o, const Complexe& c)


{ o << c.re<<”+”<<c.im<<”i”;
return o;
}
void main()
{
Complexe c1(2, 3), c2(10, 20), c3(0, 0);
c3 = c1 + c2;
cout<<c3;
cout<<c1<<c2<<c3; //ceci est réalisée grâce au retour d’un
//objet de type ostream par référence.
23
}
Exemple surcharge de l’opérateur += pour la 
classe string
classe string
// string.cc
/* This is a memory efficient string class. It allocates just
enough memory to store the string passed to it! It demonstrates
overloading the += operator. This is overloaded as a MEMBER
FUNCTION */

#include <iostream.h>
#include <string.h>
class String {
private:
char *str;
public:
// Constructor
String(char* ptr);
// member functions
void print();
// Overloaded operators
const String&
g operator
p += (
(const String&
g a);
);
};
24
Exemple surcharge de l’opérateur += pour la 
classe string
classe string

25