Vous êtes sur la page 1sur 11

Chapitre 10 :

La Surcharge des opérateurs

1. la Surcharge des opérateurs


C++ autorise la surcharge des fonctions membres ou indépendantes en fonction
du nombre et du type d’arguments. C++ autorise également la surcharge des
opérateurs portant au moins sur un objet, tel que l’addition (+), la soustraction (-) ou
l’affectation (=) entre objets.

Par convention, un opérateur op reliant deux opérandes a et b est vu comme

une fonction prenant en argument un objet de type a et un objet de type b.

 Ainsi, l'écriture "a op b" est traduite en langage C++ par un appel :

op(a, b);

Par convention également, un opérateur renvoie un objet du type de ses

opérandes. Un opérateur est représenté par un nom composé du mot operator suivi

de l'opérateur (operator+(), operator/()...).

En C++ les opérateurs suivants peuvent être surchargés :

+ - * / & ^ &

| ~ ! = < > +=

-= *= /= %= ^= &= |=

<< >> >>= <<= == != <=

>= && || ++ -- ->* ,

-> [] () new new[] delete delete[]

Les opérateurs suivant ne peuvent être surchargés :

:: . .* ?:

1
Lorsqu’on surcharge les opérateurs il est très important qu’ils aient une

signification très proche de leur signification habituelle ;

 Ne pas utiliser l’opérateur + pour multiplier 2 complexes !!.

 De plus il est essentiel d’être cohérent : ‘a += b;’ et ‘a = a + b;’ doivent donner

la même valeur à ‘a’.

Pour surcharger un opérateur ‘op’, il faut définir une fonction de nom : ‘operator
op’.

Syntaxe :

type operator ‘op’ (arg)

2. Surcharge interne et externe des opérateurs


C++ autorise deux méthodes pour surcharger un opérateur :

- La surcharge interne : l’opérateur est une méthode de la classe.

- La surcharge externe : l’opérateur est une fonction amie de la classe.

Exemple 1 : Surcharge interne

#include <iostream>
using namespace std;

class point
{
int x,y;
public :

point(int, int);
void afficher();
//la surcharge des opérateurs + et *
point operator + (point);
point operator * (int);
};

void point :: afficher()

2
{
cout << "x = " << x << " \t y=" << y << endl;
}
point::point(int a=0,int b=0)
{
x=a;
y=b;
}
point point::operator+(point p1)
{
point p;
p.x=x+p1.x;
p.y=y+p1.y;
return p;
}

point point::operator*(int a)
{
point p;
p.x=x*a;
p.y=y*a;
return p;
}

main()
{
point o1(5,10);
point o2(15,20);
point R1=o2.operator+(o1);
R1.afficher();
R1.afficher();
point R2=o1.operator*(5);
R2.afficher();
R2=(o2+o1)*2;
R2.afficher();
}

3
Remarques :

 Quand l’opérateur + (par exemple) est appelé, le compilateur génère un appel

à la fonction operator+.

 Avec la fonction membre, l’expression ‘o1+o2’ sera interprétée par le


compilateur comme l’expression ‘o1.operator+(o2);’.

Exemple 2 : Surcharge externe

#include <iostream>
using namespace std;

class point
{
int x,y;
public :
point(int, int);
void afficher();
//la surcharge des opérateurs + et *
friend point operator + (point,point);
friend point operator * (point,int);
};
void point :: afficher()
{
cout << "x = " << x << " \t y=" << y << endl;
}
point::point(int a=0,int b=0)
{ x=a; y=b; }
point operator+(point p1, point p2)
{
point p;
p.x=p1.x+p2.x;
p.y=p1.y+p2.y;
return p;
}
point operator*(point p1, int a)
{
point p;
p.x=p1.x*a;
p.y=p1.y*a;
return p;
}

4
main()
{
point o1(5,10);
point o2(15,20);
point R1=operator+(o1, o2);
R1.afficher();
R1=o1+o2;
R1.afficher();
point R2=operator*(o1, 2);
R2.afficher();
R2=o1*2;
R2.afficher();
}

point R1=o2.operator+(o1); // surcharge interne


point R1=operator+(o1, o2); // surcharge externe

3. Surcharge des opérateurs de comparaison


Exemple 3 : Comparaison

#include <iostream>
using namespace std;
class point
{
int x,y;
public :

point(int, int);
void afficher();
//la surcharge des opérateurs > et <=
bool operator > (point);
bool operator <=(point);
};

void point :: afficher()


{
cout << "x = " << x << " \t y=" << y << endl;
}

5
point::point(int a=0,int b=0)
{
x=a;
y=b;
}
bool point::operator>(point p1)
{
if(x>p1.x)
return true;
else
return false;
}

bool point::operator<=(point p1)


{
if(*this>p1)
return false;
else
return true;
}

main()
{
point o1(5,10);
point o2(15,20);
if(o1>o2)
cout << "ok" << endl;
else
cout << "Non OK" << endl;

if(o1<=o2)
cout << "ok" << endl;
else
cout << "Non OK" << endl;
}

6
4. Surcharge des opérateurs d'accès
L’opérateur [] permet de modifier la valeur d’un élément de la matrice, ou d’y

avoir accès. Dans la classe tableau de l’exemple, on va définir l’opérateur []

permettant d’afficher l'élément de l’indice i.

On utilise la surcharge de l'opérateur [ ] pour que A[i] désigne l'élément voulu

pour un objet de la classe A.

 Surcharger l’opérateur ‘[ ]’ de manière à ce que ‘o[i]’ désigne l’élément du


tableau dynamique d’emplacement ‘i’ de l’objet ‘o’ de la class ‘tableau’. Le
premier opérande de ‘o[i]’ étant ‘o’.

Exemple 4 : la surcharge de l’opérateur ‘[ ]’

#include <iostream>
using namespace std;
class tableau
{
int ne;
int *p;

public :
tableau(int n, int *t)
{
ne=n;
p=new int[ne];
for(int i=0;i<ne;i++)
p[i]=t[i];
}

void affiche()
{
for(int i=0;i<ne;i++)
cout<<p[i]<<"\t";
cout<<endl;
}
int valeur(int i)
{
return p[i]; }
int operator[](int n)
{

7
return p[n];
}

~tableau(){
cout << "libiration de la memoire";
delete []p;}
};
main()
{
int *t = new int[3];
for(int i=0; i<3; i++)
t[i]=i+1;
tableau t1(3, t);
t1.affiche();
cout<<t1[1]<<endl;
cout << t1.valeur(1) << endl;
}

 Remarques :

Les opérateurs = () [] −> new delete ne peuvent être surchargés que comme des

fonctions membres.

- Quand on a le choix, l’utilisation d’une fonction membre pour surcharger un

opérateur est préférable.

 Une fonction membre renforce l’encapsulation.

Exemple 5 : la surcharge de l’opérateur ‘()’

Surcharger l’opérateur ‘( )’ de manière à ce que ‘o(i)’ désigne l’élément du


tableau dynamique d’emplacement ‘i’ de l’objet ‘o’ de la class ‘tableau’. Le premier
opérande de ‘o(i)’ étant 0.

#include <iostream>

8
using namespace std;
class tableau
{
int ne;
int *p;
public :
tableau(int n, int *t)
{
ne=n;
p=new int[ne];
for(int i=0;i<ne;i++)
p[i]=t[i];
}
void affiche()
{for(int i=0;i<ne;i++)
cout<<p[i]<<"\t"; cout<<endl;}

int operator()(int n){ return p[n]; }

~tableau(){
cout << "libiration de la memoire";
delete []p;}
};
main()
{
int *t = new int[3];
for(int i=0; i<3; i++)
t[i]=i+1;
tableau t1(3, t);
t1.affiche();
cout<<t1(2)<<endl;}

5. Surcharges des opérateurs d’entrées/sorties

Les deux opérateurs << et >>, déjà surdéfinis au sein des classes istream et

ostream pour les différents types de base, peuvent être surdéfinis pour n'importe

quel type classe créé par l'utilisateur. Pour ce faire, il suffit de tenir compte des

remarques suivantes :

9
Ces opérateurs doivent recevoir un flot en premier argument, ce qui empêche

de les surdéfinir sous la forme d’une fonction membre de la classe concernée. Il

s'agira donc de fonctions indépendantes ou amies de la classe concernée et ayant un

prototype de la forme :

ostream & operator << (ostream &, type_classe )

istream & operator >> (ostream &, type_classe &)

 La valeur de retour sera obligatoirement la référence au flot concerné (reçu en


premier argument).

Exemple 6 : la surcharge des opérateur << et >>

#include <iostream>
using namespace std;
class point
{
int x,y;
public:
point(int a=0,int b=0)
{x=a; y=b;}
void affiche()
{cout << "x = " << x << " & y=" << y << endl; }

friend ostream& operator<<(ostream & , const point &);


friend istream& operator>>(istream & , point &);
};

ostream& operator<<(ostream & out, const point & p)


{
out<<"x = "<< p.x <<" y : "<<p.y<<endl;
return out;
}

istream& operator>>(istream & in, point & p){


cout<<"Entrer x : "; in>>p.x;
cout<<"Entrer y : "; in>>p.y;
return in;
}

10
main()
{
point p1(10, 10);
point p2;
cout << p1;
cin>>p2;
cout << p2;
}

11

Vous aimerez peut-être aussi