+ | - | * | / | % | ^ | & | | |
~ | ! | , | = | < | > | <= | >= |
++ | - - | << | >> | == | != | && | || |
+= | -= | /= | *= | %= | ^= | &= | |= |
<<= | >>= | [] | () | -> |
-> * |
new | delete |
:: | .* | . | ?: |
Surcharge des Opérateurs (2) |
-->
impossible de redéfinir les opérateurs pour
les types prédéfinis).
expression | fonction membre | fonction non |
membre | ||
++a | a.operator++() | operator++(a) |
a+b | a.operator+(b) | operator+(a,b) |
a=b | a.operator=(b) | impossible |
a() | a.operator()() | impossible |
a[b] | a.operator[](b) | impossible |
a-> |
a.operator-> () |
impossible |
a++ | a.operator++(1) | operator++(a,1) |
T operator++() // opérateur préfixé |
T operator++(int) // opérateur postfixé |
Opérateur d'affectation |
class String { | |
int len ; char * pt ; | |
public: | |
String(const char *ch) { | |
len = strlen(ch); | |
pt=new char[len+1]; | |
strcpy(pt,ch); | |
} | |
~ String() { delete [] pt; } |
|
} ; | |
String s1("toto"); | |
String s2("foo"); | |
s2 = s1; // recopie membre à membre | |
// s2.pt est écrasé par s1.pt | |
// Þ espace pointé par s2.pt perdu | |
s1.set("coucou"); | |
// Þ chaîne de s2 modifiée en même temps | |
// s2.len==4 et s2.pt=="coucou" |
class String { | |
int len ; char * pt ; | |
public: | |
String(const char *ch) { | |
len = strlen(ch); | |
pt=new char[len+1]; | |
strcpy(pt,ch); | |
} | |
~ String() { delete [] pt; } |
|
String& operator=(String&); | |
... | |
}; | |
// Noter le retour d'une référence | |
String& String::operator=(String& s) { | |
if (this != &s) { | |
// protection vis a vis de x=x | |
delete [] pt ; // libération mémoire | |
len = s.len; | |
pt = new char[len+1]; | |
pt = strcpy(s.pt) ; | |
} | |
return *this; | |
} |
Opérateur d'indexation |
class TabInt { | |
int *data, taille; | |
public : | |
TabInt(int dim) : taille(dim) { | |
data = new int[dim]; } | |
int& operator[](int); | |
}; |
int& TabInt::operator[](int ind) { | |
if ((ind<0) || (ind >= taille)) { | |
cout << "Erreur de borne" << endl; | |
exit(1); | |
} | |
return data[ind]; | |
} |
TabInt tab = TabInt(10); |
for (int i=0; i<10; i++) |
tab[i] = i ; |
Opérateurs +=, -=, *=, ... |
class Point { |
int x,y; ... |
public : |
Point(int a, int b) : x(a), y(b) {} |
Point(int a=0) : x(a), y(a) {} |
Point& operator+=(const Point&); |
... |
}; |
Point& Point::operator+=(const Point& p) { |
x+=p.x; y+=p.y; |
return *this; |
} |
Point p1(2,3), p2(1,2) ; |
p1 += p2 ; |
p1 += 1; // OK : p1 += Point(1) |
Opérateurs +, -, *, ... |
class Complex { |
double r,i; ... |
public : |
Complex(double = 0.0, double = 0.0); |
Complex operator+(const Complex&) ; |
}; |
Complex Complex::operator+(const Complex& p2) |
{ return Complex(r+p2.r, i+p2.i) ; } |
int main(void) { |
Complex a(1.0), b(2.,3.); |
Complex c = a + b ; // OK |
Complex d = b + 1.0;//OK: b+Complex(1.) |
Complex e = 1.0 + c; // Erreur compil. |
} |
class Complex { // ... | |
public : | |
Complex(double = 0.0, double = 0.0); | |
friend Complex operator+(const Complex&, | |
const Complex&) ; | |
}; |
Complex operator+(const Complex& p1, | |
const Complex& p2) { | |
return Complex(p1.r+p2.r, p1.i+p2.i) ; | |
} |
int main(void) { |
Complex c(1.0); |
Complex d = c + 1.0; // OK |
Complex e = 1.0 + c; // OK |
} |
Les temporaires |
compteur operator+(const compteur& c1, | |
const compteur& c2) { | |
return compteur(c1.valeur+c2.valeur) ; | |
} | |
... | |
compteur a,b,c; | |
... | |
a = b+c+4; | |
// temp1 = b+c | |
// temp2 = compteur(4) | |
// temp3 = temp1+temp2 | |
// a = temp3 |
Opérateurs d'entrées/sorties |
class Point { | |
friend ostream& operator<<( ostream&, | |
const Point&); | |
... | |
}; |
ostream& operator<<(ostream& stream, |
const Point& p) { |
return stream << p.x << " " << p.y; |
} |
Point p(2,3); |
cout << "p = " << p << endl ; |
Opérateur de conversion de type |
class Rationnel { | |
int num,den; | |
public : | |
Rationnel(int n=0, int d=1) : num(n), | |
den(d) {} | |
// op. de conversion vers double | |
operator double() const { | |
return ((double)num)/den); | |
} | |
}; |
Rationnel r = Rationnel(4) ; |
x = sqrt(double(Rationnel(2,3))); |
Opérateurs de gestion mémoire |
#include <stddef.h> | ||
class Point { | ||
private : | ||
int x,y; | ||
Point *next; | ||
static Point *freeP; | ||
static const int packNb; | ||
public : | ||
... | ||
void* operator new(size_t); | ||
void operator delete(void *); | ||
}; | ||
void* Point::operator new(size_t sz) { | ||
Point *p; | ||
if (!freeP) { | ||
size_t packSz = packNb*sz; | ||
// Alloc. espace pr packNb Points | ||
freeP = (Point *)new char[packSz]; | ||
for (int i=1,p=freeP;i<packNb;i++,p++) | ||
p-> next = p+1;// Mise en liste |
||
p-> next = 0; |
||
} | ||
p=freeP; freeP=freeP-> next; |
||
return p; | ||
} | ||
void Point::operator delete(void* pt) { | ||
((Point*)pt)-> next = freeP; |
||
freeP = (Point*)pt; | ||
} | ||
Point* Point::freeP=0; | ||
const int packNb=50; | ||
Point* p = new Point(3,4); | ||
// Point::new(sizeof(Point)) | ||
// puis Point::Point(3,4) |
Implémentation usuelle des opérateurs |
Opérateur | Réalisation | Retour |
[] | DOIT être membre | réf. à qqch |
(), -> , -> *, * |
DOIT être membre | selon cas |
++, - - | membre | réf. à l'objet |
conversion | DOIT être membre | selon cas |
!, ~ , ... (unaires) |
membre | selon cas |
= | DOIT être membre | réf. à l'objet |
+=, /=, ... | membre | réf. à l'objet |
+, -, /, ... | non-membre | nouvel objet |
<<, >> (I/O) | DOIT être non-membre | réf. à stream |
new | DOIT être membre | void* |
delete | DOIT être membre | void |