Sunteți pe pagina 1din 11

CAPITOLUL 3

Supraincarcareaoperatorilor
3
Supraincarcareaoperatorilor
4
1. Moduride supraincarcarea operatorilor2. Restrictiila
supraincarcareaoperatorilor3. Supraincarcareaoperatorilorunari4.
Membriiconstantiaiclasei5. Supraincarcareaoperatorilorinsertorsiextractor6.
Supraincarcareaoperatoruluide atribuire=7. Supraincarcareaoperatoruluide
indexare[ ]8. Supraincarcareaoperatorilornewsidelete9. Supraincarcareaoperatorului(
)10.Supraincarcarea operatorului->11.ConversiiCAP. 3
Supraincarcareaoperatorilor
5
CAP. 3
3.1. Moduride supraincarcarea operatorilor
Supra�ncarcarea(engl.,overloading)operatorilorpermiteatribuireadenoisemnificatiiope
ratoriloruzuali(operatorilor�nt�lnitipentrutipurilededatepredefinite).
Supraincarcareaoperatorilor
6
CAP. 3
3.1. Moduride supraincarcarea operatorilor
Clasareprezintauntipdedate(omultimedevaloripentrucares-
aadoptatunanumitmoddereprezentaresiomultimedeoperatiicarepotfiaplicateacestora).Ast
fel,operatorul+folosestelaadunareaadouadatedetipint,floatsaudouble,�nsaaceluiasiope
ratorisepoateatribuisemnificatiade�alipire�adouaobiectedetipsir,saudeadunareadouaob
iectedetipulcomplex,vectorsaumatrice.
Supraincarcareaoperatorilor
7
CAP. 3
3.1. Moduride supraincarcarea operatorilor
Observatie:
Operatoriisuntdejasupra�ncarcatipentruaputeaopera
asupramaimultortipuridebaza(deexemplu,operatorul+admiteoperanzidetipint,darsifloats
audouble),saupotaveasemnificatiidiferite(deexemplu,operatorul*poatefifolositpentru�
nmultireaadoioperanzinumericisaucaoperatordedeferentiere,operatorul>>poateaveasemni
ficatiadeoperatorextractorsauoperatordedeplasareladreapta,laniveldebit).
Supraincarcareaoperatorilor
8
CAP. 3
3.1. Moduride supraincarcarea operatorilor
Prinsupra�ncarcareaoperatorilor,operatiilecarepotfiexecutateasuprainstantelor(obiec
telor)uneiclasepotfifolositecasiincazultipurilordedatepredefinite.
Supraincarcareaoperatorilor
9
CAP. 3
3.1. Moduride supraincarcarea operatorilor
[<tip_val_ret>] operator <simbol_op> (<lista_declar_par>) { //��. corpulfunctiei}
Deci,limbajulC+
+permitesupraincarcareaoperatorului<op>prindefinireauneifunctiinumite
operator<simbol_op>
Exemplu: Pentru clasa punct, putem atribui operatorului + semnificatia:
expresia a+b (a, b sunt obiecte din clasa punct) reprezinta �suma� a doua puncte si
este un punct ale carui coordonate sunt date de suma coordonatelor punctelor a si
b. Astfel, supraincarcareaoperatorului+ constain definireauneifunctiicu
numeleoperator +:
Supraincarcareaoperatorilor
10
CAP. 3
3.1. Moduride supraincarcarea operatorilor
Functia trebuie sa poata accesa datele membre private ale clasei, deci
supra�ncarcarea operatorilor se poate realiza �n doua moduri:
?printr-o functie membra a clasei; ?printr-o functie prietena a clasei.
Supraincarcareaoperatorilor
11
CAP. 3
3.1. Moduride supraincarcarea operatorilor
�n situatia �n care, pentru clasa punct, supra�ncarcareaoperatorului binar de
adunare, +, se realizeaza printr-o functie membra, aceasta primeste ca parametru
implicit adresa obiectului curent (pentru care este apelata). Deci primul operand
al operatorului este transmis implicit, iar al doilea operandeste parametrul
transmis explicit.
3.1.1 SUPRA�NCARCAREA OPERATORILOR PRIN FUNCTII MEMBRE
Supraincarcareaoperatorilor
12
CAP. 3
3.1. Moduride supraincarcarea operatorilor3.1.1 SUPRA�NCARCAREA OPERATORILOR PRIN
FUNCTII MEMBRE
Exemplu:
class punct{ double x, y; public: // . . . . . . vezicapitolulanterior
punctoperator + (punct); }; //Metodeleclaseipunct�������� punctpunct::operator +
(puncta) {punctp; p.x=x + a.x; //echivalentcup.x=this->x+a.x; p.y=y + a.y;
//echivalentcu p.y=this->y+a.y; return p; }intmain() { punctA(1.1, 2.2);
A.afisare(); punctB(-5.5, -6.6); B.afisare(); punctC; C=A+B; C.afisare(); C=A+B+C;
C.afisare(); }
Expresia C=A+B este interpretata ca C = A.operator + (B). Expresia C=A+B+C poate fi
interpretata, �n functie de compilator, astfel: Unele compilatoare creaza un obiect
temporar T: T = A.operator + (B) C = T.operator+ (C) Alte compilatoare
interpreteaza expresia ca: C=(A.operator+(B)).operator+(C).
Supraincarcareaoperatorilor
13
CAP. 3
3.1. Moduride supraincarcarea operatorilor3.1.1 SUPRA�NCARCAREA OPERATORILOR PRIN
FUNCTII PRIETENE
Consideramclasapunctdefinitaanterior.?
functiileprieteneauacceslamembriiprivatiaiunei
clase,�nsaNUprimesccaargumentimplicitpointerulcatreobiectulcurent(this)?
sasupra�ncarcamacelasioperatorbinardeadunare,+,printr-ofunctieprietenaaclaseipunct:
Supraincarcareaoperatorilor
14
CAP. 3
3.1. Moduride supraincarcarea operatorilor3.1.1 SUPRA�NCARCAREA OPERATORILOR PRIN
FUNCTII PRIETENEclass punct{ double x, y; public: // . . . . . . friend
punctoperator + (punct, punct); };//Metodeleclaseipunct��������. punctoperator +
(puncta, punctb) {punctp; p.x=a.x+ b.x; p.y=a.y+ b.y; return p; }main()
{ punctA(1.1, 2.2); A.afisare(); punctB(-5.5, -6.6); B.afisare(); punctC;
punctC=A+B; C.afisare(); C=A+B+C; C.afisare(); }
Expresia C=A+B este interpretata de compilator ca C=operator + (A, B). Expresia
C=A+B+C este evaluata tiin�ndu-se cont de regulile de prioritate si de
asociativitate a operatorului: (A+B)+C, ceea ce conduce la un apel de forma:
operator+(operator+(A, B), C).
Supraincarcareaoperatorilor
15
CAP. 3
3.1. Moduride supraincarcarea operatorilor3.1.1 SUPRA�NCARCAREA OPERATORILOR PRIN
FUNCTII PRIETENE
Observatie:
�n exemplul anterior, transmiterea parametrilor catre functia prietena de
supra�ncarcare a operatorului +se realizeaza prin valoare. Parametrii pot fi
transmisi si prin referinta, pentru a evita crearea (�n momentul apelului functiei)
unor copii locale ale parametrilor efectivi �n cei formali.
Supraincarcareaoperatorilor
16
CAP. 3
3.1. Moduride supraincarcarea operatorilor3.1.1 SUPRA�NCARCAREA OPERATORILOR PRIN
FUNCTII PRIETENE
Observatie:
La transmiterea parametrilor prin referinta, functia prietena operator +are
prototipul: punctoperator + (punct&, punct&); Pentru a proteja argumentele
transmise prin referinta la modificarile
care ar putea fi realizate asupra acestora �n corpul functiei, se poate folosi
modificatorul de acces const:
punctoperator + (constpunct&, constpunct&);
Supraincarcareaoperatorilor
17
1. Moduride supraincarcarea operatorilor2. Restrictiila
supraincarcareaoperatorilor3. Supraincarcareaoperatorilorunari4.
Membriiconstantiaiclasei5. Supraincarcareaoperatorilorinsertorsiextractor6.
Supraincarcareaoperatoruluide atribuire= 7. Supraincarcareaoperatoruluide indexare[
] 8. Supraincarcareaoperatorilornew sidelete9. Supraincarcareaoperatorului( )
10.Supraincarcarea operatorului-> 11.ConversiiCAP. 3
Supraincarcareaoperatorilor
18
CAP. 3
3.2. RESTRICTII LA SUPRA�NCARCAREA OPERATORILOR
Supra�ncarcarea operatorilor se poate realiza, deci, prin functii membre sau
functii prietene. Daca supra�ncarcam acelasi operator printr-o metoda si printr-o
functie prietena, functia prietena va avea, �ntotdeauna, un parametru �n plus fata
de metoda (deoarece functiei prietene nu i se transmite ca parametru implicit
pointerul this).
Supraincarcareaoperatorilor
19
CAP. 3
3.2. RESTRICTII LA SUPRA�NCARCAREA OPERATORILOR
Totusi, supra�ncarcarea operatorilor este supusa urmatoarelor restrictii:?Se pot
supra�ncarca doar operatorii existenti; nu se pot crea noi operatori. ?Nu se poate
modifica aritatea (numarul de operanzi) operatorilor limbajului (operatorii unari
nu pot fi supraincarcati ca operatori binari, si invers). ?Nu se poate modifica
precedenta si asociativitatea operatorilor.
Supraincarcareaoperatorilor
20
CAP. 3
3.2. RESTRICTII LA SUPRA�NCARCAREA OPERATORILOR
Totusi, supra�ncarcarea operatorilor este supusa urmatoarelor restrictii:(cont)?
operatorii supra�ncarcati pastreaza aritatea si precedenta operatorilor
predefiniti, darnumostenesc si comutativitateaacestora. ?Nu pot fi supra�ncarcati
operatorii .(operatorul selector al unui membru), .*(operatorul de deferentiere,
selectie indirecta a unui membru), ::(de rezolutie, de apartenenta, scop) si ?:
(operatorul conditional).
Supraincarcareaoperatorilor
21
CAP. 3
3.2. RESTRICTII LA SUPRA�NCARCAREA OPERATORILOR
Observatii:
?Revedetitabelulcu operatoriiexistenti, precedentasiasociativitateaacestora. ?Daca
operatorul = (de atribuire) nu este supra�ncarcat, el are o semnificatie implicita.
?Operatorii , new delete [ ] -> si de conversie explicita impun restrictii
suplimentarecare vor fi discutate ulterior.
Supraincarcareaoperatorilor
22
CAP. 3
3.2. RESTRICTII LA SUPRA�NCARCAREA OPERATORILOR
Observatii:
?Functia operator trebuie sa aiba cel putin un argument (implicit sau explicit) de
tipul clasei pentru care s-a supra�ncarcat operatorul. Astfel:oLa supra�ncarcarea
unui operator unar printr-o functie membra a clasei, aceasta are un argument
implicit de tipul clasei (obiectul care �l apeleaza) si nici un argument explicit.
La supra�ncarcarea operatorului unar printr-o functie prietena, aceasta are un
argument explicitde tipul clasei.oLa supra�ncarcarea unui operator binar printr-o
functie membra a clasei, aceasta are un argument implicit de tipul clasei (obiectul
care �l apeleaza) si un argument explicit. La supra�ncarcarea operatorului binar
printr-o functie prietena, aceasta are doua argumente explicitede tipul clasei.
Supraincarcareaoperatorilor
23
CAP. 3
3.2. RESTRICTII LA SUPRA�NCARCAREA OPERATORILOR
?Se poate atribui unui operator orice semnificatie, �nsa este de dorit ca noua
semnificatie sa fie c�t mai apropiata de semnificatia naturala.
Deexemplu,pentruadunareaadouaobiectesepoatesupra�ncarcaoperatorul*,darestemainatura
lafolosireaoperatorului+cusemnificatiadeadunare.
Supraincarcareaoperatorilor
24
CAP. 3
3.2. RESTRICTII LA SUPRA�NCARCAREA OPERATORILOR
?�n cazul supra�ncarcarii operatorilor, nu se poate conta pe comutativitatea
acestora. De exemplu, daca se supra�ncarca operatorul + pentru clasa complex
printr-o functie prietena a clasei complex, aceasta va avea prototipul: complex
operator + (complex, double)
Operatorulpoatefifolosit�nexpresiicumarfi:a+7.8(aesteobiectalclaseicomplex),darnu�n
expresiica:7.8+a.
Supraincarcareaoperatorilor
25
CAP. 3
3.2. RESTRICTII LA SUPRA�NCARCAREA OPERATORILOR
?Daca un operator trebuie sa primeasca ca prim parametru un tip predefinit, acesta
nu poate fi supra�ncarcat printr-o functie membra. ?Operatorii care prezinta si
alte particularitati, vor fi tratati separat?�n principiu, metodele care
supra�ncarca un operator nu sunt statice. Exceptia o constituie operatorii newsi
delete. ?Diferenta �ntre forma prefixata si postfixata, la supra�ncarcarea
operatorilor predefiniti ++ si --, se poate face doar de anumite compilatoare (de
exemplu, compilatorul de BorlandC, versiune>3.0, se poate face diferenta).
Supraincarcareaoperatorilor
26
1. Moduride supraincarcarea operatorilor2. Restrictiila
supraincarcareaoperatorilor3. Supraincarcareaoperatorilorunari4.
Membriiconstantiaiclasei5. Supraincarcareaoperatorilorinsertorsiextractor6.
Supraincarcareaoperatoruluide atribuire= 7. Supraincarcareaoperatoruluide indexare[
]8. Supraincarcareaoperatorilornewsidelete9. Supraincarcareaoperatorului( )
10.Supraincarcarea operatorului->11.ConversiiCAP. 3
Supraincarcareaoperatorilor
27
CAP. 3
3.3. SUPRA�NCARCAREA OPERATORILOR UNARI
Operatorii unari pot fi supra�ncarcati printr-o functie membranestatica (fara
parametri expliciti) sau printr-o functie prietena cu un parametru explicit de
tipul clasa. Ca exemplu, sa supra�ncarcam operatorul unar ++pentru clasa punct,
pentru a putea fi folosit at�t �n forma prefixata, c�t si postfixata (doar pentru
compilatoarele care permit acest lucru!!).
Supraincarcareaoperatorilor
28
CAP. 3
3.3. SUPRA�NCARCAREA OPERATORILOR UNARI
Vom folosi clasa punct implementata anterior, cu modificarea ca datele membre sunt
de tipul int.class punct{int x, y;
public: // . . .punct operator ++ (int ); //forma postfixata punct & operator++
(); //forma prefixata};punctpunct::operator ++ (int) {punctp=*this; x++; y++;return
p;} punct& punct::operator++() {x++; y++; return *this;}intmain() { punctA(11, 10);
punctC=A++;A.afisare( ); C.afisare( ); punctC=++A;A.afisare( ); C.afisare( ); }
Supraincarcareaoperatorilor
29
1. Moduride supraincarcarea operatorilor2. Restrictiila
supraincarcareaoperatorilor3. Supraincarcareaoperatorilorunari4.
Membriiconstantiaiclasei5. Supraincarcareaoperatorilorinsertorsiextractor6.
Supraincarcareaoperatoruluide atribuire= 7. Supraincarcareaoperatoruluide indexare[
] 8. Supraincarcareaoperatorilornew sidelete9. Supraincarcareaoperatorului( )
10.Supraincarcarea operatorului-> 11.ConversiiCAP. 3
Supraincarcareaoperatorilor
30
CAP. 3
3.4. MEMBRII CONSTANTI AI UNEI CLASE
O clasa poate avea membrii statici: ?date membru statice (figureaza �ntr-un singur
exemplar pentru toate instantele clasei) ?metode statice (nu li se transmite
pointerul this si pot modifica doar date membru statice). O clasa poate avea metode
constante. O metoda este declarata constanta prin utilizarea modificatorului
const�n antetul ei, dupa lista parametrilor formali. Metodele constante nu modifica
obiectul pentru care sunt apelate.
Supraincarcareaoperatorilor
31
CAP. 3
3.4. MEMBRII CONSTANTI AI UNEI CLASE
Ca oricaror variabile de tip predefinit, si obiectelorde tip definit de utilizator
li se poate aplica modificatorul const. Pentru un obiect constant este permis doar
apelul metodelor constante, a constructorilor si a destructorilor.
Supraincarcareaoperatorilor
32
1. Moduride supraincarcarea operatorilor2. Restrictiila
supraincarcareaoperatorilor3. Supraincarcareaoperatorilorunari4.
Membriiconstantiaiclasei5. Supraincarcareaoperatorilorinsertorsiextractor6.
Supraincarcareaoperatoruluide atribuire=7. Supraincarcareaoperatoruluide
indexare[ ]8. Supraincarcareaoperatorilornewsidelete9. Supraincarcareaoperatorului(
) 10.Supraincarcarea operatorului->11.ConversiiCAP. 3
Supraincarcareaoperatorilor
33
CAP. 3
3.5. SUPRAINCARCAREA OPERATORILOR INSERTORSI EXTRACTOR
Operatorul<<se numeste operatorinsertor, deoarece insereazadate �n stream-ul
(fluxul) de iesire. Operatorul>>se numeste operatorextractor, deoarece extragedate
din stream-ul (fluxul) de intrare.
Supraincarcareaoperatorilor
34
CAP. 3
3.5. SUPRAINCARCAREA OPERATORILOR INSERTORSI EXTRACTOR
�nexemplulurmator,acestioperatorisuntsupra�ncarcatipentruclasacomplex,astfel�nc�tsa
poatafifolositicapentruobiecteledetippredefinit.Exemplu:
complexz1,z2;cin>>z1>>z2;//extragevalorileluiz1siz2cout<<"z1="<<z1<<'\n';//insereaz
asirconstant,apoivaloarealuiz1cout<<"z2="<<z2<<'\n';//insereazasirconstant,apoivalo
arealuiz2
Supraincarcareaoperatorilor
35
CAP. 3
3.5. SUPRAINCARCAREA OPERATORILOR INSERTORSI EXTRACTOR
Deoarece�ntotdeaunaoperandulst�ngestedetipistream(cinesteobiectpredefinit,detipistr
eam)sauostream(coutesteobiectpredefinit,detipostream),sinudetipulintrodusprinclasa,
operatorii<<si>>potfisupra�ncarcatinumaiprinfunctiiprietene.
Supraincarcareaoperatorilor
36
CAP. 3
3.5. SUPRAINCARCAREA OPERATORILOR INSERTORSI EXTRACTOR
Prototipurileoperatorilorsunt:
(pentrutipuldedatecomplex)
friendostream&operator<<(ostream&,constcomplex&);
//operatorafisarecomplex
friendistream&operator>>(istream&,complex&);
//operatorcitirecomplex
Supraincarcareaoperatorilor
37
CAP. 3
3.5. SUPRAINCARCAREA OPERATORILOR INSERTORSI EXTRACTOR
Definitiilefunctiiloroperator:ostream&operator<<(ostream&ecran,constcomplex&z)
{ecran<<"("<<z.re;if(z.im>=0)ecran<<'+';ecran<<z.im<<"*i)";returnecran;}istream&ope
rator>>(istream&tastatura,complex&z){tastatura>>z.re>>z.im;returntastatura;}
Supraincarcareaoperatorilor
38
CAP. 3
3.5. SUPRAINCARCAREA OPERATORILOR INSERTORSI EXTRACTOR
Prototipurilefunctiiloroperator<<si>>pentruuntipabstracttip,sunt:
friendostream&operator<<(ostream&,consttip&); friendistream&operator >>
(istream&,tip&);
Supraincarcareaoperatorilor
39
CAP. 3
3.5. SUPRAINCARCAREA OPERATORILOR INSERTOR SI EXTRACTOR
Exercitiu:
Se defineste tipul de date DateTime, cu data membra _bintime, de tipul
time_t(definit �n header-ul time.h). Pentru acest tip de date s-au definit 2
constructori, metoda afis, si s-au supra�ncarcat
operatorii: +(prin doua functii prietene care pot realiza operatii de forma d+n,
respectiv n+d �n de tip �ntreg, dde tip DateTime) care aduna la data curenta un
numar de zile; +=(prin metoda); <<(operatorul insertor, prin functie prietena).
Supraincarcareaoperatorilor
40
CAP. 3
3.5. SUPRAINCARCAREA OPERATORILOR INSERTOR SI
EXTRACTOR//----------------------------------------------
datetime.h-----------------------------------------------#if !defined(__DATETIME_H)
#define __DATETIME_H #include <time.h> // functiiANSI standard "Time" #include
<iostream.h> // pentrustream-uriI/O class DateTime{ private: time_t_bintime;
public: DateTime() { time(&_bintime); } DateTime(time_tt) : _bintime(t) { } friend
DateTime operator+(DateTime d, int n) { structtm *ltime= localtime(&d._bintime);
ltime->tm_mday+= n; time_tt = mktime(ltime); return DateTime(t); }
Supraincarcareaoperatorilor
41
CAP. 3
3.5. SUPRAINCARCAREA OPERATORILOR INSERTOR SI EXTRACTORfriend DateTime operator+
(int n, DateTime d) { return d+n; } DateTimeoperator+=(intn) {structtm *ltime=
localtime(&_bintime); ltime->tm_mday+= n; _bintime= mktime(ltime); return *this; }
void afis(ostream& os) { os << ctime(&_bintime);} friend ostream&
operator<<(ostream& os, DateTime& d) {d.afis(os); return os; } }; #endif
Supraincarcareaoperatorilor
42
CAP. 3
3.5. SUPRAINCARCAREA OPERATORILOR INSERTOR SI
EXTRACTOR//-----------------------------------Programulde test
-----------------------------#include "datetime.h" intmain(void) { DateTime d1;cout
<< "Data curenta si ora = " << d1 << �\n�; d1 += 45;cout << "Peste 45 de zile, va
fi " << d1 <<�\n�; cout<< "Pesteinca5 zile, vafi "; cout<< d1+5 << endl; }
Supraincarcareaoperatorilor
43
1. Moduride supraincarcarea operatorilor2. Restrictiila
supraincarcareaoperatorilor3. Supraincarcareaoperatorilorunari4.
Membriiconstantiaiclasei5. Supraincarcareaoperatorilorinsertorsiextractor6.
Supraincarcareaoperatoruluide atribuire=7. Supraincarcareaoperatoruluide
indexare[ ] 8. Supraincarcareaoperatorilornewsidelete9.
Supraincarcareaoperatorului( ) 10.Supraincarcarea operatorului->11.ConversiiCAP. 3
1
Supraincarcareaoperatorilor
44
CAP. 3
3.6. SUPRAINCARCAREA OPERATORULUI DE ATRIBUIRE =
�ncazul�ncareoperatoruldeatribuirenuestesupra�ncarcatexplicit,compilatorulgenereaza
unulimplicit(ca�nexemplulclaseipunctsausegment).�nabsentauneisupra�ncarcariexplicit
e,operatorulcopievaloriledatelormembrealeoperanduluidrept�ndatelemembrealeoperandul
uist�ng.
/
Supraincarcareaoperatorilor
45
CAP. 3
3.6. SUPRAINCARCAREA OPERATORULUI DE ATRIBUIRE =
Exemplu:
puncta(8,9),b;b=a;/*operatoratribuireimplicit:zonadememorieocupatadeobiectulasecopi
e,bitcubit,�nzonadememorieocupatadeb:b.x=a.xsib.y=a.y*/Operatoruldeatribuireimplici
testenesatisfacator�nsituatiile�ncareobiecteleclaseiaucadatemembrepointeri,sau�nsit
uatiile�ncarememoriaestealocata�nmoddinamic.
Supraincarcareaoperatorilor
46
CAP. 3
3.6. SUPRAINCARCAREA OPERATORULUI DE ATRIBUIRE =O supra�ncarcare explicita a
operatorului pentru clasa complex (ambii operanzi de tip complex) poate fi facuta
fie prin metoda, fie prin functie prietena. class complex { double re,im; public:
complex operator = (complex ); }; complex complex::operator = (complex z)
{ re=z.re; im=z.im; return *this; //this este pointer catre obiectul curent, a �n
main} intmain() {complex a, b; a = b; //a.operator=(b); (v. figura) }
Deoarece functiaoperator = returneaza valoare de tip complex, se construieste un
obiect temporar temp, a carui valoare se atribuie lui a.
Supraincarcareaoperatorilor
47
CAP. 3
3.6. SUPRAINCARCAREA OPERATORULUI DE ATRIBUIRE =
O alta modalitate, mai eficienta, de a supra�ncarca operatorul de atribuire prin
metoda a clasei complex, este aceea prin care functia primeste ca parametru
referintacatre operandul drept (se lucreaza, astfel, chiar cu obiectul b, deoarece
z si b sunt variabile referinta; �n plus, modificatorul const interzice modificarea
operandului transmis ca parametru referinta; �n plus, nu se mai creaza obiectul
local z, se ia ca referinta obiectul existent) si returneaza o referinta (adresa
obiectului a), asa cum prezinta figura.
Supraincarcareaoperatorilor
48
CAP. 3
3.6. SUPRAINCARCAREA OPERATORULUI DE ATRIBUIRE =
complex &complex::operator=(constcomplex &z) { re=z.re; im=z.im; return *this;}
intmain() {complex a, b;a = b; //a.operator=(b); (v. figura) }
Supraincarcareaoperatorilor
49
CAP. 3
3.6. SUPRAINCARCAREA OPERATORULUI DE ATRIBUIRE =
Deasemenea, operatorul binar de atribuire poate fi supra�ncarcat prinfunctie
prietena (�n acest caz, nu primeste parametrul implicit this, deci are doi
operanzi). Paramertrii z1, z2 sunt transmisi prin referinta, deci se lucreaza chiar
cu obiectele a, b. Functia returneaza adresa obiectului a. Modificatorul const
interzice modificarea operandului drept.
Supraincarcareaoperatorilor
50
CAP. 3
3.6. SUPRAINCARCAREA OPERATORULUI DE ATRIBUIRE =class complex { double re,im;
public: friendcomplex&operator=(complex&, constcomplex&); //functie prietena
constanta }; complex &operator=(complex &z1,complex &z2) {z1.re=z2.re;z1.im=z2.im;
return z1;} intmain() {complex a, b; a = b; //a.operator=(b); (v. figura) }
Supraincarcareaoperatorilor
51
CAP. 3
3.6. SUPRAINCARCAREA OPERATORULUI DE ATRIBUIRE =
Deoarece�ntotdeaunaoperandulst�ngaloperatoruluideatribuireestedetipulclaseipentruca
resesupra�ncarca,estepreferabilcasupra�ncarcareasaserealizezeprin
metodaaclasei.
Reamintimcaasociativitateaoperatoruluiestedeladreaptalast�nga.Operatorulpoateapare�
nexpresiideforma:a=b=c=d;
Supraincarcareaoperatorilor
52
CAP. 3
3.6. SUPRAINCARCAREA OPERATORULUI DE ATRIBUIRE =//FISIERUL complex.h#define PI
3.14159265358979 #include <iostream.h> class complex { double re,im; public:
complex(double r=0,double i=0); //constructorcomplex(constcomplex&);
//constructorcopiere~complex(){cout<<"Destructor
complex("<<re<<","<<im<<")\n";} //destructor double modul(); //metodacare
returneazamodululunuicomplex
Supraincarcareaoperatorilor
53
CAP. 3
3.6. SUPRAINCARCAREA OPERATORULUI DE ATRIBUIRE =double arg(); //metodacare
returneazaargumentulunuicomplex void ipi(); // metodacare incrementeazaparteaimag.
void dpi(); //met. de decrem. a partii imag // operator + binarfriendcomplex
operator+(constcomplex&,constcomplex&); // complex + complex friendcomplex
operator+(constdouble,constcomplex &); // real + complex friendcomplex operator +
(constint,constcomplex &);//int+complexfriendcomplex operator +
(constcomplex&,constdouble); // complex + double
Supraincarcareaoperatorilor
54
CAP. 3
3.6. SUPRAINCARCAREA OPERATORULUI DE ATRIBUIRE =complex operator -(constcomplex &)
const; //operator -binar: complex -complex //operator inmultirebinar: complex *
complex friendcomplex operator *(constcomplex &,constcomplex &); complex operator
*(constcomplex ) const;
Supraincarcareaoperatorilor
55
CAP. 3
3.6. SUPRAINCARCAREA OPERATORULUI DE ATRIBUIRE =/*TEMA: friend complex operator /
(constcomplex &,constcomplex &); complex operator / (constcomplex &); */ complex &
operator + () const; //operator + unar; metoda constanta complex operator -()
const; //operator -unarcomplex &operator=(constcomplex &); complex & operator +=
(constcomplex &z); complex operator += (constdouble); complex operator -=
(constcomplex&); complex & operator /= (constcomplex &z);
Supraincarcareaoperatorilor
56
CAP. 3
3.6. SUPRAINCARCAREA OPERATORULUI DE ATRIBUIRE =/* TEMA complex operator *=
(constcomplex&); complex operator /= (constcomplex&);*/ complex & operator ++
(); //forma prefixata complex operator ++ (int); //forma postfixata complex
operator--(); //decrementarea partii reale a obiectului complex curent complex
operator ! (); //calcul. radacinii patrate a obiectului complex curent intoperator
== (complex &z); //compara doi complecsi si returneaza 1 �n caz de egalitate friend
intoperator==(complex &, complex &); //return. 1 daca 2 complecsi egali intoperator
!= (complex &); friend intoperator != (complex &, complex &); friend
ostream&operator<<(ostream&,constcomplex&); //operator afisarecomplex friend
istream& operator >> (istream&,complex&); //operator citirecomplex };
Supraincarcareaoperatorilor
57
CAP. 3
3.6. SUPRAINCARCAREA OPERATORULUI DE ATRIBUIRE =// FISIERUL complex.cpp #include
"complex.h" #include <stdlib.h> #include <math.h> inlinecomplex::complex(double r,
double i) {re=r;im=i;cout<<"Constructor implicit ptrcomplex(";
cout<<re<<","<<im<<")\n";} complex::complex(constcomplex & z)
{re=z.re;im=z.im;cout<<"Constructor copiereptrcomplex("; cout<<re<<","<<im<<")\n";}
inline double complex::modul() { return sqrt(re*re+im*im); }
Supraincarcareaoperatorilor
58
CAP. 3
3.6. SUPRAINCARCAREA OPERATORULUI DE ATRIBUIRE =double complex::arg() {double a; if
(re==0 && im==0) return (double)0; if (im==0) if (re>0) return 0.0; else return PI;
if (re==0) if (im==0) return PI/2; else return (3*PI)/2; a=atan(im/re); if (re<0)
return PI+a; if (im<0) return 2*PI+a; return a; }inline void complex::ipi() { im++;
} inline void complex::dpi() { im--; }
Supraincarcareaoperatorilor
59
CAP. 3
3.6. SUPRAINCARCAREA OPERATORULUI DE ATRIBUIRE =complex operator +(constcomplex &a,
constcomplex &b) {complex z; z.re=a.re+b.re; z.im=a.im+b.im; return z; } complex
operator +(constdouble d, constcomplex &a) {complex
z;z.re=d+a.re;z.im=a.im;returnz;} complex operator +(constintd, constcomplex &a)
{complex z;z.re=d+a.re;z.im=a.im;returnz;} complex operator +(constcomplex &a,
constdouble d) {complex z;z.re=d+a.re;z.im=a.im;returnz;} complex
complex::operator-(constcomplex &a) const{complex z;z.re=re-a.re;z.im=im-
a.im;returnz;} complex operator *(constcomplex &x,constcomplex &y) {complex
z;z.re=x.re*y.re-x.im*y.im; z.im=x.re*y.im+x.im*y.re;returnz;}
Supraincarcareaoperatorilor
60
CAP. 3
3.6. SUPRAINCARCAREA OPERATORULUI DE ATRIBUIRE =complex complex::operator
*(constcomplex x) const{complex z;z.re=re*x.re-
im*x.im;z.im=re*x.im+im*x.re;returnz;} complex & complex::operator +() const{return
*this;} complex complex::operator -() const{complex z;z.re=-re;z.im=-im;return
z;}complex & complex::operator=(constcomplex &a){re=a.re;im=a.im;return *this;} //
returneaza obiectul curent
Supraincarcareaoperatorilor
61
CAP. 3
3.6. SUPRAINCARCAREA OPERATORULUI DE ATRIBUIRE =complex &
complex::operator+=(constcomplex &x) {double re1=re*x.re-
im*x.im;doubleim1=re*x.im+im*x.re; re=re1; im=im1;return *this;} complex
complex::operator+=(constdouble d) {re+=d; return *this;} complex
complex::operator-=(constcomplex &x) {re-=x.re;im-=x.im; return *this;} complex
&complex::operator /= (constcomplex &z) {double numitor=z.re*z.re+z.im*z.im; double
re1=(double)(re*z.re+im*z.im)/numitor; double im1=(double)(im*z.re-
re*z.im)/numitor; re=re1; im=im1;return *this;}
Supraincarcareaoperatorilor
62
CAP. 3
3.6. SUPRAINCARCAREA OPERATORULUI DE ATRIBUIRE =complex & complex::operator++()
//forma prefixata {cout<<"F. prefixata!\n";re++; return *this;} complex
complex::operator ++ (int) //forma postfixata { cout<<"F.
postfixata!\n";complexz=*this; re++; return z;} complex complex::operator--()
{re--; return *this;} complex complex::operator ! () { complex w; double d,e; if
((d=modul())==0) return w; e=arg();d=sqrt(d);
e=e/2;w.re=d*cos(e);w.im=d*sin(e);return w;}
PROGRAMAREACALCULATOARELORSILIMBAJEDE PROGRAMAREII
Supraincarcareaoperatorilor
63
CAP. 3
3.6. SUPRAINCARCAREA OPERATORULUI DE ATRIBUIRE =intcomplex::operator==(complex &x)
{return re==x.re && im==x.im;} intoperator==(complex &x, complex &y) {return
(x.re==y.re && x.im==y.im);} intcomplex::operator!=(complex &x) {return !(re==x.re
&& im==x.im);} intoperator!=(complex &x, complex &y) {return !(x.re==y.re &&
x.im==y.im);} ostream&operator<<(ostream&ecran, constcomplex &z) {ecran<<"("<<z.re;
if (z.im>=0) ecran<<'+';ecran<<z.im<<"*i)"; return ecran;}
istream&operator>>(istream&tastatura, complex &z)
{tastatura>>z.re>>z.im;returntastatura;}
Supraincarcareaoperatorilor
64
CAP. 3
1
3.6. SUPRAINCARCAREA OPERATORULUI DE ATRIBUIRE =//FISIERUL de test#include
"complex.cpp"#include <conio.h>#include <stdio.h>complex a(2.0, -6.0), b;main()
{ cout<<"Intrarein main\n";complex x(3,7), y(-1, 28), z;
cout<<"b="<<b<<'\n';cout<<"x="<<x<<'\n';cout<<"y="<<y<<'\n';cout<<"z="<<z<<'\n';
cout<<"a="<<a<<'\n';cout<<"a++="<<a++<<'\n';cout<<"++a="<<++a<<'\n';
Supraincarcareaoperatorilor
65
CAP. 3
3.6. SUPRAINCARCAREA OPERATORULUI DE ATRIBUIRE =printf("Pentrucontinuareintroduun
car!\n"); getch();{ complex w; cout<<"Introducetiw:\n";cin>>w; cout<<"w cititeste:
"<<w<<'\n';w.ipi(); cout<<"Dupaincrem. p. imag:"<<w<<'\n';w.dpi();
cout<<"Dupadecrem. p. imag:"<<w<<'\n';cout<<"Modululluiw
este:"<<w.arg()<<'\n';cout<<"Argumentulluiw
este:"<<w.arg()<<'\n';printf("Pentrucontinuareintroduun car!\n"); char
rasp;cout<<"Se iesedin bloculinterior!\n";}
Supraincarcareaoperatorilor
66
CAP. 3
3.6. SUPRAINCARCAREA OPERATORULUI DE ATRIBUIRE =printf("Pentrucontinuareintroduun
car!\n");getch(); cout<<"a="<<a<<'\n'; ++a; cout<<"Dupa increm. p. reale:
"<<a<<'\n'; --a; cout<<"Dupadecrem. p. reale: "<<a<<'\n';
a=x;cout<<"x="<<x<<'\n';cout<<"Dupaatribuire: a="<<a<<'\n';getch(); a=x++;cout<<"a
= "<<a<<'\n';complexk1=a;cout<<"k="<<k1<<'\n'; a=++x;cout<<"a = "<<a<<'\n'; complex
k=a;cout<<"k="<<k<<'\n';getch(); k=-a;cout<<"-unaraplicatlui k:"<<k<<'\n';cout<<"-
k="<<-k<<'\n'; k=x+y;cout<<x<<" + "<<y<<" = "<<k<<'\n';getch(); k=4+x;cout<<" 4 +
"<< x <<" ="<<4+x<<'\n';k=a*x; cout<<a<<" * "<<x<<" = "<<k<<'\n'; }
Supraincarcareaoperatorilor
67
CAP. 3
3.6. SUPRAINCARCAREA OPERATORULUI DE ATRIBUIRE =Pentru a evita lucrul cu fisiere
care au sute de linii de cod, se folosesc doua abordari: a) Se creaza fisierul
sursa numit fractie.h(header al utilizatorului) care contine declararea clasei
fractie. Se creaza fisierul fractie.cpp�n care se implementeaza metodele clasei
fractie. �n acest fisier se include header-ul "fractie.h". Se creaza un al treilea
fisier care testeaza tipul de date fractie, �n care se include fisierului
"fractie.cpp". Se compileaza, se linkediteaza si se lanseaza �n executie fisierul
executabil obtinut.
Supraincarcareaoperatorilor
68
CAP. 3
3.6. SUPRAINCARCAREA OPERATORULUI DE ATRIBUIRE =b) Se construieste un proiect. De
exemplu, daca se lucreaza sub un mediu integrat, cum ar fi BorlandC, se creaza cele
trei fisiere (fractie.hcare contine declararea clasei, fractie.cppcare
implementeaza metodele clasei si fisierul de test (test_fractie.cpp)). Fisierul
header fractie.h va fi inclus at�t �n fractie.cpp, c�t si �n test_fractie.cpp. Din
meniul �Project� se selecteaza �Open Project�, apoi comanda �Add item��, care
permite adaugarea fisierelor fractie.cpp si test_fractie.cpp.
Supraincarcareaoperatorilor
69
CAP. 3
3.6. SUPRAINCARCAREA OPERATORULUI DE ATRIBUIRE =Pentru a evita includerea aceluiasi
fisier header de mai multe ori, se folosesc directivele de compilare conditionata.
Exemplu:
#ifndef_fractie_h#include "fractie.h" #define _fractie_h#endif
70
CAP. 3
To be continued�
Supraincarcareaoperatorilor
Supraincarcareaoperatorilor
71
1. Moduride supraincarcarea operatorilor2. Restrictiila
supraincarcareaoperatorilor3. Supraincarcareaoperatorilorunari4.
Membriiconstantiaiclasei5. Supraincarcareaoperatorilorinsertorsiextractor6.
Supraincarcareaoperatoruluide atribuire=7. Supraincarcareaoperatoruluide
indexare[ ] 8. Supraincarcareaoperatorilornewsidelete9.
Supraincarcareaoperatorului( ) 10.Supraincarcarea operatorului-> 11.ConversiiCAP. 3
1.Conceptede bazaale programariiorientate
peobiecte2.Clasesiobiecte3.Supraincarcareaoperatorilor4.Creareaierarhiilorde
clase5.Operatiide intrare/ iesirein limbajulC++6.Implementariale modelelorde
date7.Functiisiclasegenerice8.ExceptiisitratareaacestoraCuprinsulCursului
2
Programareacalculatoarelorsilimbajede programareII

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