Sunteți pe pagina 1din 24

UNIVERSITATEA TEHNICĂ “GH.

ASACHI” DIN IAŞI


FACULTATEA DE ELECTRONICĂ, TELECOMUNICAŢII ŞI TEHNOLOGIA INFORMAŢIEI

Programare orientată pe obiecte

Cursul nr. 5

2021
Cursul nr. 5
Cuprins
FACULTATEA DE ELECTRONICĂ, TELECOMUNICAŢII ŞI TEHNOLOGIA INFORMAŢIEI

1. Supraîncărcarea operatorilor în C++

2. Supraîncărcarea operatorilor binari


UNIVERSITATEA TEHNICĂ “GH. ASACHI” DIN IAŞI

3. Supraîncărcarea operatorilor unari

4. Exemplu – clasa Complex


Cursul nr. 5
1. Supraîncărcarea operatorilor în C++
În exemplul de mai jos, pentru adunarea a două numere complexe s-a definit o funcție suma(), iar
FACULTATEA DE ELECTRONICĂ, TELECOMUNICAŢII ŞI TEHNOLOGIA INFORMAŢIEI

pentru afișarea unui număr complex este definită funcția afisComplex().


Ar fi mai simplu dacă s-ar putea folosi operatorul + pentru suma, respectiv operatorul << pentru
afișare.
#include <iostream>
UNIVERSITATEA TEHNICĂ “GH. ASACHI” DIN IAŞI

using namespace std;


class Complex {
int main(void) {
double real, imag;
public: Complex z0;
Complex(double real = 0.0, double imag = z0.afisComplex();
0.0) :real(real), imag(imag) { } Complex z1(1.0, 2.0);
void afisComplex() const; z1.afisComplex();
Complex& suma(Complex&); Complex z2(4.7);
}; z2.afisComplex();
void Complex::afisComplex() const {
z2.suma(z1);
cout << " Nr complex: " << "(" << real
<< ", " << imag << ")" << endl; z2.afisComplex();
} return 0;
Complex& Complex::suma(Complex& c1) { }
real += c1.real;
imag += c1.imag;
return *this;
}
Cursul nr. 5
1. Supraîncărcarea operatorilor în C++
➢ Tipurile abstracte de date au fost concepute astfel încât să permită folosirea lor de
FACULTATEA DE ELECTRONICĂ, TELECOMUNICAŢII ŞI TEHNOLOGIA INFORMAŢIEI

către utilizator într-o manieră similară tipurilor predefinte. În acest scop se pune la
dispoziţia programatorului mecanismul de supraîncărcare a operatorilor.
➢ Limbajul C++ permite supraîncărcarea numai pentru operatorii existenţi (nu se pot
crea operatori noi).
UNIVERSITATEA TEHNICĂ “GH. ASACHI” DIN IAŞI

➢ Nu se pot supraîncărca următorii operatori :


. (punct)
:: (rezoluţie)
.*(selecţie a membrilor prin intermediul pointerilor la membri)
?: (condiţional)
sizeof
typeid
➢ Nu se pot supraîncărca directivele adresate preprocesorului # şi ##.
➢ Prin supraîncărcare nu se schimbă n-aritatea, prioritatea sau asociativitatea
operatorilor (acestea rămânând cele predefinite).
Cursul nr. 4
1. Supraîncărcarea operatorilor în C++
➢ Următorii operatori pot fi supraîncărcați:
FACULTATEA DE ELECTRONICĂ, TELECOMUNICAŢII ŞI TEHNOLOGIA INFORMAŢIEI

+ - * / % ^
& | ~ ! && ||
UNIVERSITATEA TEHNICĂ “GH. ASACHI” DIN IAŞI

++ -- << >> , <


<= == != > >= =
+= -= *= /= %= &=
|= ^= <<= >>= [ ] ( )
-> ->* new delete
Cursul nr. 5
1. Supraîncărcarea operatorilor în C++
➢ Supraîncărcarea operatorilor se poate face folosind funcţii membru sau funcţii friend.
FACULTATEA DE ELECTRONICĂ, TELECOMUNICAŢII ŞI TEHNOLOGIA INFORMAŢIEI

➢ Sintaxa generală pentru supraîncărcarea operatorilor este :


- pentru supraîncărcarea cu funcţii membru :

tip_returnat NumeClasa :: operator op(lista_parametri) { corp}


UNIVERSITATEA TEHNICĂ “GH. ASACHI” DIN IAŞI

- pentru supraîncărcarea cu funcţii friend :

tip_returnat operator op(lista_parametri) { corp}

➢ În general, pentru acelaşi operator, funcţiile friend au un argument în plus în lista de


parametri, funcţiile membru având implicit transmis operandul pentru care au fost
apelate (prin intermediul pointerului this).
Cursul nr. 5
2. Supraîncărcarea operatorilor binari
➢ Operatorii binari pot fi funcții membru cu un parametru sau funcții friend cu doi parametri.
FACULTATEA DE ELECTRONICĂ, TELECOMUNICAŢII ŞI TEHNOLOGIA INFORMAŢIEI

Supraîncărcarea operatorului +

class Fractie {
private:
int numarator;
UNIVERSITATEA TEHNICĂ “GH. ASACHI” DIN IAŞI

int numitor;
public:
const Fractie operator+(const Fractie&) const;
friend const Fractie operator+(const Fractie&, const Fractie&);
};

// supraincarcarea operator+ binar, ca functie membru


const Fractie Fractie::operator+(const Fractie& a) const {
Fractie sum;
sum.numarator = a.numarator * this->numitor + a.numitor * this->numarator;
sum.numitor = a.numitor * this->numitor;
return sum;
}
Fractie f1(1,2), f2(2,3);
Compilatorul “traduce” f1 + f2 astfel: f1.operator+(f2), deci funcția operator+ este apelată de
obiectul f1 și are ca parametru obiectul f2.
Cursul nr. 5
2. Supraîncărcarea operatorilor binari
FACULTATEA DE ELECTRONICĂ, TELECOMUNICAŢII ŞI TEHNOLOGIA INFORMAŢIEI

class Fractie {
private:
int numarator;
int numitor;
public:
const Fractie operator+(const Fractie&) const;
UNIVERSITATEA TEHNICĂ “GH. ASACHI” DIN IAŞI

friend const Fractie operator+(const Fractie&, const Fractie&);


};

// supraincarcarea operator+ binar, ca functie friend


const Fractie operator+(const Fractie& a, const Fractie& b) {
Fractie sum;
sum.numarator = a.numarator * b.numitor + a.numitor * b.numarator;
sum.numitor = a.numitor * b.numitor;
return sum;
}

Fractie f1(1,2), f2(2,3);


Compilatorul “traduce” f1 + f2 astfel: apel operator+(f1, f2)
Cursul nr. 5
2. Supraîncărcarea operatorilor binari
Supraîncărcarea operatorului de atribuire =
FACULTATEA DE ELECTRONICĂ, TELECOMUNICAŢII ŞI TEHNOLOGIA INFORMAŢIEI

➢ Operatorul de atribuire se poate supraîncărca numai prin funcţii membru.


➢ Pentru a asigura un comportament similar operatorului de atribuire ce operează
asupra tipurilor de date standard, metoda ce supraîncarcă operatorul de atribuire
UNIVERSITATEA TEHNICĂ “GH. ASACHI” DIN IAŞI

trebuie sa returneze o referinţă către clasa căreia îi apaţine.


➢ O atenţie specială trebuie acordată situaţiilor în care clasa manevrează zone de
memorie alocate dinamic, caz în care trebuie asigurată operarea corectă inclusiv în
cazul autoatribuirii.
➢ Pentru operatorii de tip op= este necesară supraîncărcarea explicită, nefiind suficientă
supraîncărcarea separată pentru op şi respectiv =.
➢ Forma generală de supraîncărcare a operatorului de atribuire este :

NumeClasa& NumeClasa:: operator = (const NumeClasa & operand) {


………
return *this;
}
Cursul nr. 5
2. Supraîncărcarea operatorilor binari

Supraîncărcarea operatorului de atribuire =


FACULTATEA DE ELECTRONICĂ, TELECOMUNICAŢII ŞI TEHNOLOGIA INFORMAŢIEI

class Fractie {
private:
int numarator;
UNIVERSITATEA TEHNICĂ “GH. ASACHI” DIN IAŞI

int numitor;
public:
const Fractie operator+(const Fractie&) const;
friend const Fractie operator+(const Fractie&, const Fractie&);
Fractie& operator=(const Fractie&);
};

Fractie& Fractie::operator=(const Fractie& r) {


numarator = r.numarator;
numitor = r.numitor;
return *this;
}
Cursul nr. 5
2. Supraîncărcarea operatorilor binari
Supraîncărcarea operatorului de atribuire =
FACULTATEA DE ELECTRONICĂ, TELECOMUNICAŢII ŞI TEHNOLOGIA INFORMAŢIEI

Ce se întâmplă dacă se încearcă o auto-atribuire? Fractie a(5, 6);


a = a;

Fractie& Fractie::operator=(const Fractie& r) {


if (&r != this) {
UNIVERSITATEA TEHNICĂ “GH. ASACHI” DIN IAŞI

numarator = r.numarator;
numitor = r.numitor;
}
return *this;
}

//Supraincarcarea operatorului de atribuire pentru clasa Sir


Sir& Sir::operator=(const Sir& sursa) {
if (this != &sursa) {
delete[]psir;
lung = sursa.lung;
psir = new char[lung + 1];
strcpy(psir, sursa.psir);
}
return *this;
}
Cursul nr. 5
2. Supraîncărcarea operatorilor binari
Supraîncărcarea operatorilor de extracție >> și de inserție <<
FACULTATEA DE ELECTRONICĂ, TELECOMUNICAŢII ŞI TEHNOLOGIA INFORMAŢIEI

➢ Se pot supraîncărca doar ca funcții friend

class Fractie {
private:
int numarator;
UNIVERSITATEA TEHNICĂ “GH. ASACHI” DIN IAŞI

int numitor;
public:
friend ostream& operator<<(ostream&, const Fractie&);
friend istream& operator>>(istream&, Fractie&);
};

ostream& operator<<(ostream& output, const Fractie& r) {


output << r.numarator << "/" << r.numitor;
return output;
}

istream& operator>>(istream& input, Fractie& r) {


input >> r.numarator >> r.numitor;
return input;
}

➢ De ce se returnează referință la clasă?


Cursul nr. 5
3. Supraîncărcarea operatorilor unari
➢ Operatorii unari pot fi funcții membru fără niciun parametru sau funcții friend cu
FACULTATEA DE ELECTRONICĂ, TELECOMUNICAŢII ŞI TEHNOLOGIA INFORMAŢIEI

un parametru.
Supraîncărcarea operatorilor de incrementare ++ / decrementare --
➢ În notație prefixată: incrementează/decrementează și apoi returnează valoarea
1. Supraîncărcarea ca funcție membru
UNIVERSITATEA TEHNICĂ “GH. ASACHI” DIN IAŞI

NumeClasa& NumeClasa:: operator op_inc/dec_pre () {


………
return *this;
}

class Fractie { Fractie& Fractie::operator++() {


private: numarator = numarator + numitor;
int numarator; return *this;
int numitor; }
public:
Fractie& operator++();
};

Compilatorul interpretează ++p astfel: p.operator++().


Cursul nr. 5
3. Supraîncărcarea operatorilor unari
2. Supraîncărcarea ca funcție friend
NumeClasa& operator op_inc/dec_pre () {
FACULTATEA DE ELECTRONICĂ, TELECOMUNICAŢII ŞI TEHNOLOGIA INFORMAŢIEI

NumeClasa rezultat;
………
return rezultat;
}
UNIVERSITATEA TEHNICĂ “GH. ASACHI” DIN IAŞI

class Fractie {
private:
int numarator;
int numitor;
public:
friend Fractie& operator++(Fractie& r);
};

Fractie& operator++(Fractie& r) {
Fractie temp;
temp.numarator = r.numarator + r.numitor;
temp.numitor = r.numitor;
return temp;
}

Compilatorul interpretează ++p astfel: operator++(p).


Cursul nr. 5
3. Supraîncărcarea operatorilor unari
Supraîncărcarea operatorilor de incrementare ++ / decrementare --
FACULTATEA DE ELECTRONICĂ, TELECOMUNICAŢII ŞI TEHNOLOGIA INFORMAŢIEI

➢ În notație postfixată: incrementează/decrementează dar returnează valoarea inițială.


Varianta postfixată folosește un parametru fictiv (dummy) de tip int.
1. Supraîncărcarea ca funcție membru
UNIVERSITATEA TEHNICĂ “GH. ASACHI” DIN IAŞI

NumeClasa NumeClasa:: operator op_inc/dec_post (int)


// Se introduce un parametru fictiv de tip int .
//Chiar şi în antetul funcţiei acest parametru nu are nume.
// Compilatorul foloseşte această informaţie pentru a face distincţie între cele două notaţii
{
NumeClasa temp(*this); // se crează o copie a stării curente a obiectului
// incrementarea/decrementarea ce afectează efectiv obiectul care a apelat operatorul
………
return temp; // se returnează obiectul (o copie a acestuia mai precis!) cu starea de
// dinaintea incrementării/decrementării
}
Cursul nr. 5
3. Supraîncărcarea operatorilor unari
FACULTATEA DE ELECTRONICĂ, TELECOMUNICAŢII ŞI TEHNOLOGIA INFORMAŢIEI

class Fractie {
private:
int numarator;
int numitor;
UNIVERSITATEA TEHNICĂ “GH. ASACHI” DIN IAŞI

public:
Fractie operator++(int);
};

Fractie Fractie::operator++(int) {
Fractie temp = *this;
this->numarator = this->numarator + this->numitor;
return temp;
}

Compilatorul interpretează p++ astfel: p.operator++(int).


Cursul nr. 5
3. Supraîncărcarea operatorilor unari
Supraîncărcarea operatorilor de incrementare ++ / decrementare --
FACULTATEA DE ELECTRONICĂ, TELECOMUNICAŢII ŞI TEHNOLOGIA INFORMAŢIEI

2. Supraîncărcarea ca funcție friend

NumeClasa NumeClasa:: operator op_inc/dec_post (NumeClasa& obj, int)


// Se introduce un parametru fictiv de tip int .
UNIVERSITATEA TEHNICĂ “GH. ASACHI” DIN IAŞI

//Chiar şi în antetul funcţiei acest parametru nu are nume.


// Compilatorul foloseşte această informaţie pentru a face distincţie între cele două notaţii
{
NumeClasa temp(obj); // se crează o copie a stării curente a obiectului
// incrementarea/decrementarea ce afectează efectiv obiectul care a apelat operatorul
………
return temp; // se returnează obiectul (o copie a acestuia mai precis!) cu starea de
// dinaintea incrementării/decrementării
}
Cursul nr. 5
3. Supraîncărcarea operatorilor unari
FACULTATEA DE ELECTRONICĂ, TELECOMUNICAŢII ŞI TEHNOLOGIA INFORMAŢIEI

class Fractie {
private:
int numarator;
int numitor;
UNIVERSITATEA TEHNICĂ “GH. ASACHI” DIN IAŞI

public:
friend Fractie operator++(Fractie&, int);
};

Fractie operator++(Fractie& f,int) {


Fractie temp(f);
f.numarator = f.numarator + f.numitor;
return temp;
}

Compilatorul interpretează p++ astfel: operator++(p,int).


Cursul nr. 5
4. Exemplu – clasa Complex
FACULTATEA DE ELECTRONICĂ, TELECOMUNICAŢII ŞI TEHNOLOGIA INFORMAŢIEI

#include <iostream>
using namespace std;
class Complex
{
double real;
UNIVERSITATEA TEHNICĂ “GH. ASACHI” DIN IAŞI

double imag;
public:
Complex(double real = 0.0, double imag = 0.0);
//constructor cu parametri
Complex(const Complex&); //constructor de copiere
~Complex() { cout << "Destructor" << endl; }
//destructor
Complex operator + (const Complex&) const;
friend Complex operator + (double, const Complex&);
friend istream& operator >>(istream &, Complex&);
friend ostream& operator <<(ostream &, const Complex&);
};
Cursul nr. 5
4. Exemplu – clasa Complex
FACULTATEA DE ELECTRONICĂ, TELECOMUNICAŢII ŞI TEHNOLOGIA INFORMAŢIEI

//constructor cu parametri
Complex::Complex(double real, double imag) : real(real),
imag(imag) {
cout << "Constructor cu parametri" << endl;
UNIVERSITATEA TEHNICĂ “GH. ASACHI” DIN IAŞI

//constructor de copiere
Complex::Complex(const Complex& c) {
real = c.real; imag = c.imag;
cout << "Constructor de copiere" << endl;
}
Cursul nr. 5
4. Exemplu – clasa Complex
FACULTATEA DE ELECTRONICĂ, TELECOMUNICAŢII ŞI TEHNOLOGIA INFORMAŢIEI

Complex Complex :: operator + (const Complex& z) const {


cout << "Operatorul + fct membru ce aduna 2 nr complexe" << endl;
Complex temp;
temp.real = real + z.real;
temp.imag = imag + z.imag;
UNIVERSITATEA TEHNICĂ “GH. ASACHI” DIN IAŞI

return temp;
}

Complex operator + (double x, const Complex& z) {


cout << "Operatorul + fct friend ce aduna un nr real cu un nr complex"
<< endl;
Complex temp;
temp.real = x + z.real;
temp.imag = z.imag;
return temp;
}
Cursul nr. 5
4. Exemplu – clasa Complex
FACULTATEA DE ELECTRONICĂ, TELECOMUNICAŢII ŞI TEHNOLOGIA INFORMAŢIEI

istream& operator >>(istream & in, Complex& z) {


in>>z.real>>z.imag;
cout << " s-a apelat operatorul >> " << endl;
return in;
}
UNIVERSITATEA TEHNICĂ “GH. ASACHI” DIN IAŞI

ostream& operator <<(ostream &out, const Complex& z) {


out<<z.real<<"+i*"<<z.imag<<endl;
cout << "s-a apelat operatorul << " << endl;
return out;
}
Cursul nr. 5
4. Exemplu – clasa Complex
int main(void) {
Complex z1; // z1: 0.0 +i*0.0
FACULTATEA DE ELECTRONICĂ, TELECOMUNICAŢII ŞI TEHNOLOGIA INFORMAŢIEI

cout << "z1 = ";


cout << z1 << endl;
const Complex z2(2.0, 3.0);
cout << "z2=";
cout << z2 << endl;
UNIVERSITATEA TEHNICĂ “GH. ASACHI” DIN IAŞI

Complex z3;
cout << "Dati nr complex z3" << endl;
cin >> z3;
cout << "z3=";
cout << z3 << endl;
Complex z4;
z4 = 5.7 + z2;
cout << "z4=";
cout << z4 << endl;
Complex c5(-6.8); // -6.8 +i*0.0
cout << c5 << endl;
c5 = z4 + z3;
cout << c5 << endl;

return 0;
Cursul nr. 5
4. Exemplu – clasa Complex
Constructor cu parametri
z1 = 0+i*0
s-a apelat operatorul <<
FACULTATEA DE ELECTRONICĂ, TELECOMUNICAŢII ŞI TEHNOLOGIA INFORMAŢIEI

Constructor cu parametri
z2=2+i*3
s-a apelat operatorul <<

Constructor cu parametri
Dati nr complex z3
2.5 1.2
s-a apelat operatorul >>
z3=2.5+i*1.2
UNIVERSITATEA TEHNICĂ “GH. ASACHI” DIN IAŞI

s-a apelat operatorul <<

Constructor cu parametri
Operatorul + fct friend ce aduna un nr real cu un nr complex
Constructor cu parametri
Constructor de copiere
Destructor
Destructor
z4=7.7+i*3
s-a apelat operatorul <<

Constructor cu parametri
-6.8+i*0
s-a apelat operatorul <<

Operatorul + fct membru ce aduna 2 nr complexe


Constructor cu parametri
Constructor de copiere
Destructor
Destructor
10.2+i*4.2
s-a apelat operatorul <<

Destructor
Destructor
Destructor
Destructor
Destructor

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