Sunteți pe pagina 1din 51

Universitatea Constantin Brncui Trgu-Jiu

Facultatea de Inginerie
Departamentul de Automatic, Energie i Mediu

Programare orientat pe
obiecte
LECTOR DR. ADRIAN RUNCEANU

Curs 5
Suprancrcarea operatorilor
(partea II)

Curs - Programare orientat pe obiecte C++/Java

01.11.2011

Curs 5
3

1. Suprancrcarea operatorului de atribuire


(=)
2. Suprancrcarea operatorului de indexare
([ ])
3. Suprancrcarea operatorului apel de
funcie (())
4. Suprancrcarea operatorilor new i delete

Curs - Programare orientat pe obiecte C++/Java

01.11.2011

1. Suprancrcarea operatorului de
atribuire(=)
4

Atunci cand se utilizeaza operatorul =,


fara supraincarcare, se realizeaza o copiere
bit cu bit.
Aceasta nu inseamna, ca intotdeauna
obtinem rezultatele dorite.
Acest lucru se intampla, deoarece cele
doua obiecte care formeaza atribuirea:
ex. a = b, primesc aceeasi adresa.
Curs - Programare orientat pe obiecte C++/Java

01.11.2011

1. Suprancrcarea operatorului de
atribuire(=)
5

In cazul in care obiectul b se distruge,

atunci, obiectul a va avea o adresa


spre un obiect care nu mai exista.
Pentru a putea inlatura acest neajuns,
trebuie sa suprancrcm operatorul
=.

Curs - Programare orientat pe obiecte C++/Java

01.11.2011

1. Suprancrcarea operatorului de
atribuire(=)
6

Operatorul = este binar.


Dac acesta este suprancrcat
prin utilizarea unei funcii membru,
atunci primul operand este obiectul
curent, iar al doilea operand este
parametrul funciei.
Curs - Programare orientat pe obiecte C++/Java

01.11.2011

1. Suprancrcarea operatorului de
atribuire(=)
7

Limbajul C++ permite programatorului s

defineasc diverse operaii cu obiecte ale


claselor, folosind simbolurile operatorilor
standard.
Un tip clas se poate defini mpreun cu un set
de
operatori
asociai,
obtinui
prin
suprancrcarea operatorilor existeni.
n acest fel, se efectueaz operaii specifice cu
noul tip la de simplu ca i n cazul tipurilor
standard.
Curs - Programare orientat pe obiecte C++/Java

01.11.2011

1. Suprancrcarea operatorului de
atribuire(=)
8

Exemplu

Considerm clasa sir, n care fiecare


obiect reine adresa unui ir de caractere.
Astfel, data membru adr reine adresa
unui pointer ctre ir, iar irul va fi alocat
dinamic cu ajutorul operatorului new ntr-o
zon de memorie disponibil.
Curs - Programare orientat pe obiecte C++/Java

01.11.2011

1. Suprancrcarea operatorului de
atribuire(=)
9

Clasa va avea:
un

constructor care aloc spaiu de memorie


pentru irul de caractere
un destructor care elibereaz zona de memorie
alocat unui ir de caractere
o metod afis() folosit pentru afiarea irului
i
o metod de copiere realizat prin
suprancrcarea operatorului =

Curs - Programare orientat pe obiecte C++/Java

01.11.2011

1. Suprancrcarea operatorului de
atribuire(=)
10

Aceast metod are rolul ca la o atribuire a = b,


unde a i b sunt obiecte de tip ir:
s elibereze memoria reinut de irul de caractere a crui
adres o conine data membru adr a lui a
s aloce spaiu pentru irul reinut de b
s copieze irul reinut de b n acest spaiu de memorie

Dup aceast operaie, irul care era iniial


reinut numai b este alocat n dou locuri diferite n
memoria disponibil, iar pointerii ctre cele doua
locuri sunt reinui de datele membru ale obiectelor
a i b.
Curs - Programare orientat pe obiecte C++/Java

01.11.2011

1. Suprancrcarea operatorului de
atribuire(=)
11

#include<iostream.h>
#include<string.h>
class sir{
char *adr;
public:
sir(char s[]);
~sir();
void afis();
void operator=(sir& sirul);
};
Curs - Programare orientat pe obiecte C++/Java

01.11.2011

1. Suprancrcarea operatorului de
atribuire(=)
12

sir::sir(char s[ ])
{
cout<<"Constructor"<<endl;
adr = new char[strlen(s) + 1];
strcpy(adr,s);
}
sir::~sir()
{
cout<<"Destructor"<<endl;
delete[ ] adr;
adr = 0;
}
Curs - Programare orientat pe obiecte C++/Java

01.11.2011

1. Suprancrcarea operatorului de
atribuire(=)
13

void sir::afis()
{
cout<<adr<<endl;
}
void sir::operator=(sir& sirul)
{
cout<<"Operator = "<<endl;
delete[ ] adr;
adr = new char[strlen(sirul.adr) + 1];
strcpy(adr, sirul.adr);
}
Curs - Programare orientat pe obiecte C++/Java

01.11.2011

1. Suprancrcarea operatorului de
atribuire(=)
14

int main(void)
{
sir s("un sir"), t("alt sir");
s.afis();
t.afis();
s = t;
t.~sir();
s.afis();
cout<<"Sf. program"<<endl;
}
Curs - Programare orientat pe obiecte C++/Java

01.11.2011

1. Suprancrcarea operatorului de
atribuire(=)
15

Dupa executia programului se va afisa:

Curs - Programare orientat pe obiecte C++/Java

01.11.2011

Curs 5
16

1. Suprancrcarea operatorului de
atribuire(=)
2. Suprancrcarea operatorului de indexare
([ ])
3. Suprancrcarea operatorului apel de
funcie(())
4. Suprancrcarea operatorilor new i delete

Curs - Programare orientat pe obiecte C++/Java

01.11.2011

2. Suprancrcarea operatorului de
indexare ([ ])
17

Operatorul de indexare [ ] este binar i are forma:


expresie_1[expresie_2]
Pentru suprancrcarea acestui operator trebuie s
folosim o funcie operator[ ], care trebuie s fie
membr a clasei, s fie nestatic i s aib forma:
x[n] sau x.operator[ ] (n)
Al doilea operand, care are rolul indexului, poate fi
la suprancrcare de orice tip.
Curs - Programare orientat pe obiecte C++/Java

01.11.2011

2. Suprancrcarea operatorului de
indexare ([ ])
18

Exemplu 2:

Programul urmtor ilustreaz un mod de


utilizare a operatorului [ ].
Ideea programului este aceea de a crea
un tablou de nregistrri care conine
informaii de tip medical despre persoane.

Curs - Programare orientat pe obiecte C++/Java

01.11.2011

2. Suprancrcarea operatorului de
indexare ([ ])
19

Se dorete accesul la nregistrri ct mai uor


posibil, n mai multe moduri:
dup nume
dup greutate
dup numrul de ordine

Curs - Programare orientat pe obiecte C++/Java

01.11.2011

2. Suprancrcarea operatorului de
indexare ([ ])
20

n prima cutare, pentru a face ct mai uor

accesul la nregistrri dup numele persoanelor,


se va face suprancrcarea operatorului de
indexare [ ] avnd ca parametru un ir de
caractere care indic numele persoanei cutate.
n al doilea caz, pentru a face ct mai uor
accesul la nregistrri dup greutatea persoanei,
vom face suprancrcarea operatorului de
indexare avnd ca parametru de tip float care
indic greutatea persoanei cutate.
Curs - Programare orientat pe obiecte C++/Java

01.11.2011

2. Suprancrcarea operatorului de
indexare ([ ])
21

#include<iostream.h>
#include<string.h>
class analize;
class pers
{
// datele personale

char nume[35];
double greutate;
int varsta;
friend analize;
public:
// functii de introducere persoane si tiparire

void init(char *s, double gr, int v);


void tipar();
};
Curs - Programare orientat pe obiecte C++/Java

01.11.2011

2. Suprancrcarea operatorului de
indexare ([ ])
22

void pers::init(char *s, double gr, int v)


{
strcpy(nume,s);
greutate=gr;
varsta=v;
}
void pers::tipar()
{
if(*this) cout<<endl<<"Persoana:
"<<nume<<"\tGreutatea :
"<<greutate<<"\tVarsta : "<<varsta;
else cout<<"Nu exista"<<endl;
}
Curs - Programare orientat pe obiecte C++/Java

01.11.2011

2. Suprancrcarea operatorului de
indexare ([ ])
23

// definim clasa care contine analizele mai multor persoane

class analize
{
pers *sir;
int n;
public:
// definire constructori

analize() { n=5; sir=new pers[5]; }


analize(int nr) { n=nr; cout<<n; sir=new
pers[n]; }
Curs - Programare orientat pe obiecte C++/Java

01.11.2011

2. Suprancrcarea operatorului de
indexare ([ ])
24

// supraincarcare operatori

void introd();
pers *operator[] (char *);
pers *operator[] (double);
pers *operator[] (int);
};

Curs - Programare orientat pe obiecte C++/Java

01.11.2011

2. Suprancrcarea operatorului de
indexare ([ ])
25

void analize::introd()
{
for(int i=0;i<n;i++)
{
cout<<endl;
cout<<"Persoana "<<i+1<<" : ";
cin>>sir[i].nume;
cout<<"Greutatea: ";
cin>>sir[i].greutate;
cout<<"Varsta: ";
cin>>sir[i].varsta;
}
}
Curs - Programare orientat pe obiecte C++/Java

01.11.2011

2. Suprancrcarea operatorului de
indexare ([ ])
26

//supraincarcare pentru a permite cautarea inregistrarilor


dupa nume

pers *analize::operator[ ] (char *nume)


{
for(int i=0;i<n;i++)
if(strcmp(sir[i].nume,nume)==0) return
&sir[i];
return NULL;
}
Curs - Programare orientat pe obiecte C++/Java

01.11.2011

2. Suprancrcarea operatorului de
indexare ([ ])
27

//supraincarcare pentru a permite cautarea inregistrarilor dupa


greutate

pers *analize::operator[] (double g)


{
for(int i=0;i<n;i++)
if(sir[i].greutate==g) return &sir[i];
return NULL;
}

Curs - Programare orientat pe obiecte C++/Java

01.11.2011

2. Suprancrcarea operatorului de
indexare ([ ])
28

pers *analize::operator[] (int index)


{
if(index<=n) return &sir[index-1];
else
return NULL;
}

Curs - Programare orientat pe obiecte C++/Java

01.11.2011

2. Suprancrcarea operatorului de
indexare ([ ])
29

int main(void)
{
char c; int nr;
cout<<"Cate analize efectuati ? "; cin>>nr;
analize t(nr); t.introd();
while(1)
{
cout<<endl<<"Optiunea [g]reutate,
[n]ume, [i]ndex, [e]xit ? ";
cin>>c;
Curs - Programare orientat pe obiecte C++/Java

01.11.2011

2. Suprancrcarea operatorului de
indexare ([ ])
30

switch(c)
{
case 'g' : double g;
cout<<"Greutatea: ";cin>>g;
t[g]->tipar();
break;
case 'n' : char n[100];
cout<<"Numele: ";cin>>n;
t[n]->tipar();
break;
case 'i' : int i;
cout<<"Nr. de index: ";cin>>i;
t[i]->tipar();
break;
case 'e': return;
}
}
}
Curs - Programare orientat pe obiecte C++/Java

01.11.2011

Curs 5
31

1. Suprancrcarea operatorului de
atribuire(=)
2. Suprancrcarea operatorului de indexare
([ ])
3. Suprancrcarea operatorului apel de
funcie(())
4. Suprancrcarea operatorilor new i delete

Curs - Programare orientat pe obiecte C++/Java

01.11.2011

3. Suprancrcarea operatorului apel


de functie - ()
32

Cand este realizata supraincarcarea


operatorului apel de functie, aceasta nu
va insemna o noua varianta de supraincarcare
a unei functii, ci supraincarcarea unui
operator binar nestatic de forma:
expresie (lista_expresii);

Curs - Programare orientat pe obiecte C++/Java

01.11.2011

3. Suprancrcarea operatorului apel


de functie - ()
33

Mentionam specificul utilizarii acestei


functii operator:
evaluarea si verificarea listei de argumente
se face intocmai ca pentru o functie
obisnuita
chiar daca operatorul este binar, functia
operator poate avea oricate argumente
Acesta deoarece al doilea argument este
considerat o lista de argumente.
Atunci cand lista de parametrii este vida,
al doilea argument poate lipsi.
Curs - Programare orientat pe obiecte C++/Java

01.11.2011

3. Suprancrcarea operatorului apel


de functie - ()
34

Exemplu 3:

Acest exemplu foloseste operatorul ()


pentru parcurgerea unei liste simple.

Curs - Programare orientat pe obiecte C++/Java

01.11.2011

3. Suprancrcarea operatorului apel


de functie - ()
35

#include<iostream.h>
#include<stdlib.h>
struct elem{
int inf;
elem *adr;
// se initializeaza camp inf cu n

elem(int n, struct elem *p): inf(n),


adr(p){}
};
Curs - Programare orientat pe obiecte C++/Java

01.11.2011

3. Suprancrcarea operatorului apel


de functie - ()
36

class list{
elem *prim,*p;
public:
// functie de afisare element curent

void afispoz()
{ cout<<"Elementul de pe pozitia curenta
are valoarea "<<p->inf<<endl;}
//primul element va avea adresa absoluta zero

list(void) { prim = NULL; };

Curs - Programare orientat pe obiecte C++/Java

01.11.2011

3. Suprancrcarea operatorului apel


de functie - ()
37

//crearea listei care va avea un numar dat de


elemente

list(int);
// supraincarcarea operatorului realizeaza pozitionarea la
nodul urmator;
//Daca pozitia curenta este la sfarsitul listei, atunci nodul
urmator va fi primul element al listei

elem *operator() ();


// supraincarcarea operatorului determina avansarea nodului
curent cu un numar dat de pozitii

elem *operator() (int);


};
Curs - Programare orientat pe obiecte C++/Java

01.11.2011

3. Suprancrcarea operatorului apel


de functie
()
38
list::list(int nr)
{
int inf;
if(nr<=0)
{ cout<<"Eroare la initializarea listei!";
cout<<endl<<"Introduceti "<<nr<<" valori ";
cin>>inf;
prim=new elem(inf,NULL);
elem*q=prim;
for(int i=1;i<nr;i++)
{
cin>>inf;
p=new elem(inf,NULL);
q->adr=p;
q=p;
}
p=prim;
}
Curs - Programare orientat pe obiecte C++/Java

exit(1); }

01.11.2011

3. Suprancrcarea operatorului apel


de functie - ()
39

elem *list::operator() ()
{
elem *poz=p;
poz = p->adr ? p->adr+1 : prim;
return p=poz;
}

Curs - Programare orientat pe obiecte C++/Java

01.11.2011

3. Suprancrcarea operatorului apel


de functie - ()
40

elem *list::operator() (int nr)


{
for(int i=1;i<nr;i++)
(*this) (); // se pozitioneaza cu nr-1 pozitii
return (*this)(); // valoarea returnata este data de ultima
pozitionare

Curs - Programare orientat pe obiecte C++/Java

01.11.2011

3. Suprancrcarea operatorului apel


de functie - ()
41

int main()
{
list l(6);
l();
l.afispoz();
l(2);
l.afispoz();
}

Curs - Programare orientat pe obiecte C++/Java

01.11.2011

Curs 5
42

1. Suprancrcarea operatorului de
atribuire(=)
2. Suprancrcarea operatorului de indexare
([ ])
3. Suprancrcarea operatorului apel de
funcie(())
4. Suprancrcarea operatorilor new i delete

Curs - Programare orientat pe obiecte C++/Java

01.11.2011

4. Suprancrcarea operatorilor new i


delete
43

Functiile operator new si delete pot fi


suprancrcate de catre utilizator cu
conditia ca acestea sa fie membre ale clasei.
Ele sunt in mod implicit de tip static.
Functia operator new are ca parametru
tipul size_t si intoarce un pointer de tip
void continand adresa zonei alocate.
Ea are prototipul:
void *operator new(size_t);
Curs - Programare orientat pe obiecte C++/Java

01.11.2011

4. Suprancrcarea operatorilor new i


delete
44

Indicarea tipului size_t este obligatorie in C++

chiar daca tipul size_t este echivalent cu tipul


unsigned int.
Operatorul
new suprancrcat pastreaza
proprietatea
de
a
apela
intotdeauna
constructorul clasei dupa alocarea dinamica a
obiectului.
Calculul dimensiunii zonei de memorie si
generarea obiectului raman in sarcina
compilatorului.
Curs - Programare orientat pe obiecte C++/Java

01.11.2011

4. Suprancrcarea operatorilor new i


delete
45

Functia operator delete trebuie sa


primeasca ca parametru un pointer de tipul
clasei asociate sau pointer la void,
continand adresa obiectului ce va eliminat.
Functia nu intoarce nici o valoare.
Are prototipul:
void *operator delete(void *);
Curs - Programare orientat pe obiecte C++/Java

01.11.2011

4. Suprancrcarea operatorilor new i


delete
46

Operatorul
delete
suprancrcat
pastreaza proprietatea de a apela intotdeauna
destructorul clasei inainte de a elibera
memoria alocata dinamic obiectului.
Utilizarea versiunilor standard new si
delete se poate face cu ajutorul operatorului
de rezolutie (::).

Curs - Programare orientat pe obiecte C++/Java

01.11.2011

4. Suprancrcarea operatorilor new i


delete
47

Exemplu 4:
Exemplu de suprancrcare a operatorilor new
si delete:
#include<iostream.h>
class exemplu
{
int a, b, c;
static short l;

Curs - Programare orientat pe obiecte C++/Java

01.11.2011

4. Suprancrcarea operatorilor new i


delete
48

public:
exemplu()
{
cout<<Apel constructor exemplu <<endl; }
~exemplu()
{
cout<<Apel destructor exemplu <<endl; }
void *operator new(size_t ln)
{
cout<<Operator new redefinit ! ;
return (void *) new char[ln];
}
Curs - Programare orientat pe obiecte C++/Java

01.11.2011

4. Suprancrcarea operatorilor new i


delete
49

void *operator delete(void *p)


{
cout<<Operator delete redefinit ! ;
delete[l] (char*)p;
}
};

Curs - Programare orientat pe obiecte C++/Java

01.11.2011

4. Suprancrcarea operatorilor new i


delete
50

Importanta practica a redefinirii operatorilor


new si delete este subliniata in urmatoarele doua
idei:
Se pot gestiona mult mai bine alocarile, verificarile
si setarile speciale in cazul datelor alocate prin
intermediul lor;
O utilizare speciala poate fi aceea in care dupa
epuizarea memoriei speciale de tip heap, se poate
face alocarea in alte zone de memorie (un fisier de
pe disc poate fi folosit ca memorie virtuala in acest
caz).
Curs - Programare orientat pe obiecte C++/Java

01.11.2011

51

ntrebri?

Curs - Programare orientat pe obiecte C++/Java

01.11.2011