Sunteți pe pagina 1din 3

Redefinirea operatorilor 43

3. Redefinirea operatorilor

O facilitate extrem de puternica a limbajului C++ este dreptul


programatorului de a adauga operatorilor limbajului si alte sensuri decât cele
predefinite. Cu alte cuvinte, este vorba despre o redefinire a operatorilor
limbajului C++, fara a se pierde vechile sensuri. Termenul consacrat în
literatura de specialitate pentru aceasta operatiune este cel de overloading
operators.
Redefinirea operatorilor (sau supraîncarcarea operatorilor) se poate
face în doua moduri: fie sub forma de functii membre, fie ca si functii
friend. Redefinirea unui operator presupune declararea unei functii al carei
nume este format din cuvântul cheie operator, un spatiu, si simbolul
operatorului redefinit.
O utilizare imediata a facilitatii de overlo ading operators este în
cazul claselor care implementeaza tipuri de date folosite în matematica.
Exemplul de mai jos prezinta o clasa care încapsuleaza comportarea
numerelor complexe.

Exemplul 3.1:

#include <stdio.h>

class Complex
{
float re, im;
public:
Complex(float real=0, float imag=0):re(real), im(imag){}

void print(){printf(“%f+i*%f”, re, im);}

Complex& operator +(Complex&);


// operatorul + este definit ca si functie membru

friend Complex& operator -(Complex&, Complex&);


// operatorul * este definit ca si functie friend
};
44 Programarea aplicatiilor Windows în Visual C++. Partea I
Complex& Complex::operator +(Complex& c)
{
this->re += c.re;
this->im += c.im;
return(*this);
}

Complex& operator -(Complex& a, Complex& b)


{
// aici este necesara crearea unui nou obiect de tip
// Complex
return *new Complex(a.re-b.re, a.im-b.im);
}

void main()
{
Complex a(0, 1), b(2, 3), c(4, 5);
a = a+b;
a.print();
a = a+b+c;

// operatorul + returneaza o referinta, deoarece el


// trebuie sa poata fi concatenat în expresii ca cea de
// mai sus!!…
// expresia de mai sus este expandata de compilator sub
// forma a = a.operator +(b.operator +(c))

a.print();
a = a-b-c; // din acelasi motiv operator – returneaza o
// referinta!
a.print();
}

Unii dintre operatori (operatorul new, operatorul delete, operatorul


[], operatorul () si operatorul =) necesita precautii suplimentare în cazul
redefinirii lor. Dintre acestia, cel mai des întâlnit este operatorul =.
Daca o clasa nu redefineste operatorul =, compilatorul ataseaza
clasei respective un operator = implicit, care efectueaza o copie bit cu bit a
operandului din dreapta sa în operandul din stânga sa. Situatia este identica
cu cea în care se genereaza un constructor de copiere implicit. Daca clasa
contine membri de tip pointer, se ajunge la situatia în care doi pointeri
pointeaza spre aceeasi zona de memorie, care poate avea efecte dezastruoase
daca se elibereaza unul din pointeri si apoi se acceseaza memoria prin al
Redefinirea operatorilor 45

doilea pointer. De aceea se recomanda redefinirea operatorului = doar în


cazul claselor care nu au membri de tip pointer.
Operatorul = este apelat în situatii de genul:

class B ob1, ob2;


ob2 = ob1; // apel operator =, redefinit explicit sau
// furnizat de compilator!

Un exemplu de redefinire a operatorului = este prezentat mai jos:

Exemplul 3.2:

class Example
{
int* ptr;
public:
Example(int i=0){ptr = new int(i);}
~Example(){delete ptr;}

Example& operator =(Example&);


};

Example& Example::operator =(Example& e)


{
if(this == &e)
return *this;
// atentie la expresii de genul e=e!
*ptr = *e.ptr; // copiaza continutul pointerului e.ptr în
// this->ptr !
return *this;
}

void main()
{
Example e1(1), e2(2), e3(3);
e1 = e2 = e3;
// operatorul = returneaza o referinta la un obiect
// Example pentru a putea fi concatenat în expresii precum
// cea de mai sus, care este expandata de compilator sub
// forma e1.operator =(e2.operator =(e3));
}

S-ar putea să vă placă și