Vous êtes sur la page 1sur 25

8.

Operators and
enumerated types
8 Operators and enumerated types
Learning Objectives
• 8.1 Overloading operators – the basics
• 8.2 Enumerated types
• 8.3.Overloaded operators in detail
• 8.4 Overloaded operators in detail (continued)
8.1.2 Operators – a glance at the past (2)

38

"AB " + "BC" -- > "ABBC"


Surcharge d’opérateurs

C++ vous permet de surdéfinir les opérateurs


existants, c’est-à-dire de leur donner une nouvelle
signification lorsqu’ils portent (en partie ou en
totalité) sur des objets de type classe.
Surcharger les opérateurs
int A=2;
int B=3;
int C;

double A1=2.1;
double B1=3.1,
double C1;

main() {
C = A + B;
C1= A1+B1;
}
Le mécanisme de la surcharge d’opérateurs

si op est un opérateur binaire, la notation est:


a op b est équivalente à : operator op (a, b)
la même notation est équivalente à :
a.operator op (b)
Le mécanisme de la surdéfinition
d’opérateurs

C=A+B C = operator+(A,B) .

D = A + B + C D = A + (B + C) , D = A + operator+(B,C)

Soit D = operator+(A,operator+(B,C))
Opérateurs et fonctions
class complexe { Le code suivant montre une implémentation de
private: l'opérateur += sur la classe complexe.
... += est implémenté en tant que fonction membre
public:
...
complexe& operator+= (const complexe&) ;
};
complexe& complexe::operator+=(const complexe& c) {
r += c.r;
i += c.i; Notez bien:Il est toujours préférable de renvoyer une référence plutôt qu'un objet, pour des
questions de performances: en effet, renvoyer un objet signifie effectuer une copie,
return *this; opération éventuellement longue pour des objets volumineux, alors que renvoyer une
} référence signifie renvoyer simplement...une adresse. Opération très rapide, et
indépendante de la taille de l'objet. C'est ainsi que operator+= renvoie une référence.
Opérateurs et fonctions

complexe operator+(const complexe& a, const complexe& b)


{
complexe r=a;
r += b;
return r;
};
#include <iostream>
using namespace std;
class point{ Surdéfinition d'opérateur
int x, y ; avec une fonction amie
public :
point (int abs=0, int ord=0) { // constructeur
x=abs ;y=ord ;
} main ( ){
friend point operator+ (point, point); point a(1,2); a.affiche() ;
void affiche () { point b(2,5); b.affiche() ;
cout << "coordonnees: " << x << " " << y << "\n" ; point c ;
} c = a+b ;
}; // c = operator + (a, b) ;
point operator+ (point a, point b) { c.affiche() ;
point p ; c = a+b+c;
coordonnees: 1 2
p.x = a.x + b.x ; // c =operator + (operator + (a, b), c);
p.y = a.y + b.y; coordonnees: 2 5 c.affiche() ;
return p ; coordonnees: 3 7 }
} coordonnees: 6 14
#include <iostream> Surdéfinition d'opérateur
using namespace std;
class point{ avec une fonction membre
int x, y ;
public :
point (int abs=0, int ord=0) { // constructeur
x=abs ;y=ord ;
}
point operator+ (point) ;
void affiche () {
cout << "coordonnées: " << x << " " << y << "\n" ;
}
}; main ( ){
point point::operator+ (point a){ point a(1,2); a.affiche() ;
point p ; point b(2,5); b.affiche() ;
p.x = x + a.x ; point c ;
p.y = y + a.y; c = a+b ; // c= a.operator+(b) ;
return p ; c.affiche() ;
} c = a+b+c; // c = (a.operator+(b)).operator + (c);
c.affiche() ;
}
Énoncé
Soit une classe vecteur3d définie comme suit :
class vecteur3d{
float x, y, z ;
public :
vecteur3d (float c1=0.0, float c2=0.0, float c3=0.0){
x = c1 ; y = c2 ; z = c3 ;
}
};
Définir les opérateurs == et != de manière qu’ils permettent de
tester la coïncidence ou la non-coïncidence de deux points :
a) en utilisant des fonctions membres;
b) en utilisant des fonctions amies.
Réponse: Avec des fonctions membre
class vecteur3d
{ float x, y, z ;
public :
vecteur3d (float c1=0.0, float c2=0.0, float c3=0.0) {
x = c1 ; y = c2 ; z = c3 ;
}
int operator== (vecteur3d) ;
int operator!= (vecteur3d) ;
};
int vecteur3d::operator== (vecteur3d v){
if ( (v.x == x) && (v.y == y) && (v.z ==z) ) return 1 ;
else return 0 ;
}
int vecteur3d::operator!= (vecteur3d v){
return ! ( (*this) == v ) ;
}
class vecteur3d{ Vecteur3d.h Réponse: Avec des fonctions amies
float x, y, z ;
public : #include <iostream>
vecteur3d (float c1=0.0, float c2=0.0, float c3=0.0) using namespace std ; main.cpp
{ main()
x = c1 ; y = c2 ; z = c3 ; {
} vecteur3d v1 (3,4,5), v2 (4,5,6), v3 (3,4,5);
friend int operator== (vecteur3d, vecteur3d) ;
friend int operator!= (vecteur3d, vecteur3d) ; cout << "v1==v2 : " << (v1==v2) <<
}; " v1!=v2 : " << (v1!=v2) << "\n" ;
int operator== (vecteur3d v, vecteur3d w){ cout << "v1==v3 : " << (v1==v3) <<
if ( (v.x == w.x) && (v.y == w.y) && (v.z == w.z) ) " v1!=v3 : " << (v1!=v3) << "\n" ;
return 1 ; }
else

}
return 0 ; Q,02
int operator != (vecteur3d v, vecteur3d w){
return ! ( v == w ) ; v1==v2 : 0 v1!=v2 : 1
}
v1==v3 : 1 v1!=v3 : 0
8.2 Enumerated types
8.2.6 Enumerated types – how do we use
them? (2)
enum weekday {Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday};

weekday day = Wednesday; //OK


int day = SUNDAY; //is OK
weekday day = 0; //?? invalid conversion from 'int' to 'weekday'

weekday day = static_cast<weekday>(0);


or weekday f = (weekday)0;

enum weekday {Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday};


8.2.7 Enumerated types – how do we use them? (3)
enum Symbols {ALPHA = -1, BETA = 1, GAMMA};

ALPHA← -1
BETA← 1
GAMMA← 2
8.2.8 Enumerated types – how do we use
them? (4)

enum letters {A = 1, B = 0, C, D};

enum letters {A = 1, B = 0, C, D, A = 1}
#include <iostream> 8.2.10 Enumerated types –
using namespace std;
class Animals { how do we use them? (6)
public:
enum names {DOG, CAT, CHUPACABRA};
};

class Commands { enum Animals {DOG, CAT, CHUPACABRA};


public:
enum names {LS, CD, CAT}; enum Commands {LS, CD, CAT};
};

int main(void) {
Animals::names a = Animals::CAT;
Commands::names c = Commands::CAT;
return 0;
}
8.2.12 Enumerated types – how do we use
them? (8)
#include <iostream>
using namespace std;
enum weekday
{SUNDAY,MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY};
int main(void) {
weekday d = SATURDAY;
d = weekday(d + 1); The + operator is unaware of weekdays at all and may skip
from SATURDAY to literally nowhere, leaving the permitted
return 0; type domain.
}
Question: why can’t we use the following form?
d = d + 1;
enum weekday {SUNDAY,MONDAY,TUESDAY,WEDNESDAY,
THURSDAY,FRIDAY,SATURDAY};
weekday operator+(weekday day, int days) {
return weekday((int(day) + days) % 7);
}
int main(void) {
weekday d = SATURDAY;
d = d + 1;
return 0;
}
8.2.13 Enumerated types – how do we use them? (9)
We can avoid these problems by overloading the + operator.
We’ve done it in such a crafty way →
weekday operator+(weekday day, int days) {
return weekday((int(day) + days) % 7);
}
Now, adding an int to a weekday will take into account the cyclical nature of days and
weeks, e.g. SUNDAY + 15 will result in MONDAY.
Note the following line:
return weekday((int(day) + days) % 7);
Can we write it in a simpler form, like this?
return weekday((day + days) % 7);
No, we can’t. The expression ‘day + days’ will invoke our overloaded + operator
recursively and the program will crash. We have to explicitly express our will to add
two ints, not a weekday and an int.
#include <iostream>
using namespace std;
enum weekday {SUNDAY,MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY};

weekday operator+(weekday day, int days) {


return weekday((int(day) + days) % 7);
}

int main(void) { 8.2.13 Enumerated types –


weekday d = SATURDAY;
cout << "day: " << d << endl;
how do we use them? (9)
d = d + 1;
cout << "day: " << d << endl;
d = d + 15; day: 6 Q.03
cout << "day: " << d << endl; day: 0
return 0;
} day: 1
8.2.14 Enumerated types –
#include <iostream>
using namespace std;
how do we use them? (10)
enum weekday {SUNDAY,MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY};
weekday operator+(weekday day, int days) {
return weekday((int(day) + days) % 7);
} int main(void) {
ostream& operator<< (ostream &strm, weekday day) { weekday d = SATURDAY;
switch(int(day)) { d = d + 16;
case SUNDAY: strm << "SUNDAY"; break; cout << d << endl;
case MONDAY: strm << "MONDAY"; break;
return 0;
case TUESDAY: strm << "TUESDAY"; break;
case WEDNESDAY: strm << "WEDNESDAY"; break; }
case THURSDAY: strm << "THURSDAY"; break;
case FRIDAY: strm << "FRIDAY"; break;
case SATURDAY: strm << "SATURDAY"; break;
default: strm << "Somewhere inside the depths of time..."; break;
}
return strm; We’re going to equip our code with the ability to output
} the weekday type values in a human readable form.

Vous aimerez peut-être aussi