Extras din curs
3. Modalitati de supraîncarcare a operatorilor.
O functie operator supraîncarcata poate fi introdusa ca functie membra (în general nestatica) sau functie prieten (functie nemembra).
Declararea unei functii membra nestatica specifica urmatoarele:
1) functia poate accesa partea privata a declaratiei clasei
2) functia este în domeniul clasei
3) functia trebuie apelata dintr-un obiect
O functie membra statica satisface numai primele doua conditii, în timp ce o functie prietena a unei clase satisface numai prima conditie.
O functie operator având ca prim argument un tip primitiv nu poate fi functie membru.
Functiile care modifica reprezentarea unui obiect necesita acces la datele membri, deci trebuie sa apartina clasei. Ele sunt functii membrecu argumente referinte neconstante.
Daca se doresc conversii implicite pentru termenii functiei operator, aceasta va fi functie nemembra cu argumente referinte constante. Aceste functii implementeaza operatorii care nu necesita operanzi L-valori (adica se aplica tipurilor fundamentale). Acestia sunt în general operatorii binari. Necesitatea accesului la reprezentare determina definirea lor ca functii prieten.
Operatorii care produc o noua valoare din valorile argumentelor (de exemplu operatorul+) se definesc în afara clasei.
Daca nu sunt necesare conversii de tip, alegerea între functie membru si functie prieten ramâne la latitudinea programatorului.
O functie nemembra foloseste numai argumente explicite, în timp ce o functie membra foloseste argumentul implicit this.
Argumentele clase, transmise prin valoare se copiaza în stiva neeconomic. Se prefera în acest caz argumentele referinte constante.
Daca valoarea întoarsa de functie este o referinta, atunci aceasta nu poate fi o variabila automatica (locala functiei). Ea nu poate fi nici o variabila statica locala, deoarece operatorul poate fi folosit de mai multe ori într-o expresie. Valoarea de întoarcere trebuie sa fie alocata în memoria libera (heap) sau sa fie preluata dintr-un buffer de obiecte statice.
Întoarcerea unei referinte la obiectul modificat se realizeaza prin return *this.
Se cauta minimizarea numarului de functii care au acces la reprezentarea interna a unei clase, prevazându-se functii de acces.
În mod obligatoriu sunt functii membre: constructorii, destructorii, functiile virtuale, etc.
4. Operatori supraîncarcati ca functii prieten.
Operatorii folositi în mod uzual pot fi unari sau binari. Utilizarea unui operator binar sub forma a#b este interpretata ca operator#(a,b)
Asadar, un operator binar va fi reprezentat printr-o functie nemembra cu doua argumente, iar un operator unar, printr-o functie nemembra cu un singur argument.
Argumentele se iau clase sau referinte constante la clase (pentru o preluare economica, asigurând protectia datelor)
Vom exemplifica pentru clasa Cplx:
class Cplx{
double re, im;
public:
Cplx(double x=0, double y=0);
Cplx(const Cplx& z);
//operatori binari
friend Cplx operator+(const Cplx& s, const Cplx& d);
friend Cplx operator-(const Cplx& s, const Cplx& d);
friend Cplx operator*(const Cplx& s, const Cplx& d);
friend Cplx operator/(const Cplx& s, const Cplx& d);
//operatori de comparatie
friend int operator==(const Cplx& s, const Cplx& d);
friend int operator!=(const Cplx& s, const Cplx& d);
//operatori unari
friend Cplx operator-(const Cplx& z);
friend Cplx operator!(const Cplx& z); //conjugat
friend Cplx& operator++(Cplx& z); //prefix
friend Cplx operator—-(Cplx& z,int); //postfix
};
//definitii operatori în afara domeniului clasei
Cplx operator+(const Cplx& s, const Cplx& d){
return Cplx(s.re+d.re,s.im+d.im);
};
Cplx operator-(const Cplx& s, const Cplx& d){
return Cplx(s.re-d.re,s.im-d.im);
};
Preview document
Conținut arhivă zip
- Supraincarcarea operatorilor.doc