Sunteți pe pagina 1din 15

CAPITOLUL 3

Supraincarcareaoperatorilor

(continuare)

Supraincarcareaoperatorilor

1. Moduride supraincarcarea operatorilor2. Restrictiila supraincarcareaoperatorilor3.


Supraincarcareaoperatorilorunari4. Membriiconstantiaiclasei5.
Supraincarcareaoperatorilorinsertorsiextractor6. Supraincarcareaoperatoruluide atribuire=7.
Supraincarcareaoperatoruluide indexare[ ] 8. Supraincarcareaoperatorilornewsidelete9.
Supraincarcareaoperatorului( ) 10.Supraincarcarea operatorului-> 11.ConversiiCAP. 3

Supraincarcareaoperatorilor

CAP. 3

3.7. SUPRAINCARCAREA OPERATORULUI DE INDEXARE

[]

Operatorulde indexareesteun operator binar, utilizatsub forma:

<nume>[<expresie>].

Să considerăm clasa vector, definită astfel: class vector{ private: intnrcomp; //nr. componentedouble
*tabcomp; //tabloulcomponentelor; adresade începutpublic: double &operator[](int); }

Supraincarcareaoperatorilor

CAP. 3

3.7. SUPRAINCARCAREA OPERATORULUI DE INDEXARE [ ]

Pentrutipulabstractvector,operatoruldeindexarepoatefisupraîncărcat,astfelîncâtsăpermităaccesareaele
mentuluideindicen.Înacestcaz,operatoruldeindexaresepoatesupraîncărcaprintr-
ofuncţiemembrăaclasei(deoareceoperandulstângestedetipulclasei),şipoatefifolositsubforma:v[n]
(undevesteobiectalclaseivector;n-expresieîntreagă).Expresiav[n]esteechivalentăcuv.operator[](n)
(apelulexplicitalfuncţieioperator[]).

Supraincarcareaoperatorilor

CAP. 3
3.7. SUPRAINCARCAREA OPERATORULUI DE INDEXARE [ ]

Transferulparametruluicătrefuncţiacaresupraîncarcăoperatorulsepoatefaceprinvaloaresauprinreferinţă.Î
nmodobligatoriu,funcţiatrebuiesăreturnezereferinţacătreelementulaflatpepoziţian(pentruapermiteeven
tualelemodificărialeelementului,deoarecevector[n]estelvalue).

Supraincarcareaoperatorilor

CAP. 3

3.7. SUPRAINCARCAREA OPERATORULUI DE INDEXARE [ ]

Pentru un tip abstract, prototipul funcţiei membre care supraîncarcă operatorul de indexare este :

<tip_element> & <tip>::operator [ ] (constint);

oconstprotejează argumentul la modificările accidentale

În cazul în care operatorul se supraîncarcă printr-o funcţie prietenă, prototipul funcţiei este:

<tip_elem> & operator [ ] (<tip>, constint);

Supraincarcareaoperatorilor

CAP. 3

3.7. SUPRAINCARCAREA OPERATORULUI DE INDEXARE [ ]Exerciţiul 1: În exemplul următor, un fişier este


tratat ca un

vector de bytes. Se implementează tipurile FileLoc şi File. #include <stdio.h> #include <iostream.h> //
Clasa"FileLoc" class File; class FileLoc{private: File* p_file; fpos_tfile_loc; FileLoc(File& f, fpos_tloc):
p_file(&f), file_loc(loc){} public: friend File; void operator=(char c); void operator=(constchar* str);
operator constchar(); };

Supraincarcareaoperatorilor

10

CAP. 3

3.7. SUPRAINCARCAREA OPERATORULUI DE INDEXARE [ ]// Clasa"File" class File {private: FILE* fp; //
ANSI C, pointer catreFILE public: friend FileLoc; File(constchar* name) // Constructor de
deschiderefisierpentrucitiresiscriere{fp= fopen(name, "r+"); } ~File() { fclose(fp);} // Destructor,
inchidefisierFileLocoperator[](fpos_tloc) // operator []; creazao instantaa claseiFileLoc{fseek(fp, loc,
SEEK_SET);return FileLoc(*this,loc); } };

Supraincarcareaoperatorilor

11
CAP. 3

3.7. SUPRAINCARCAREA OPERATORULUI DE INDEXARE


[ ]//--------------------------------------------------------------//
Functiilemembre//--------------------------------------------------------------// operator = (char) // Utilizatsub
forma f[n] = c, undef[n] esteun obiectde tip FileLocsic estede tip char // pentru memorarea caracterului
in fisier void FileLoc::operator=(char c) { if(p_file->fp!= NULL) { putc(c, p_file->fp); } }

Supraincarcareaoperatorilor

12

CAP. 3

3.7. SUPRAINCARCAREA OPERATORULUI DE INDEXARE [ ]// operator = (char *) // Utilizatsub forma f[n] =
"sir", undef[n] este un obiectde tipFileLoc// pentru memorarea sirului in fisier void
FileLoc::operator=(constchar* str) { if(p_file->fp!= NULL) {fputs(str, p_file->fp); } } // operator
constchar( ) // Utilizatsub forma c=f[n], undef[n] este un obiectde tipFileLocsi c este un caracter// pentru
citirea unui caracter din fisier FileLoc::operator constchar() { if(p_file->fp!= NULL) {return getc(p_file-
>fp); } return EOF; }

Supraincarcareaoperatorilor

13

CAP. 3

3.7. SUPRAINCARCAREA OPERATORULUI DE INDEXARE


[ ]//--------------------------------------------------------------// Testarea claselor File si FileLoc // Inaintede
executie, trebuiecreatfisierul"test.dat" intmain() { File f("test.dat"); inti; char c; cout << "Primii14 bytes =
" << '\n'; for(i=0; i<14; i++) {c = f[i]; cout<< c; } cout<< '\n'; // Modificareaprimilor7 bytes cu 'X' for(i=0;
i<7; i++) f[i] = 'X'; // Afisarea, din nou, a primelor14 caracterecout << "Iar primii14 bytes = " << '\n';
for(i=0; i<14; i++) {c = f[i]; cout<< c; } cout<< '\n';

Supraincarcareaoperatorilor

14

CAP. 3

3.7. SUPRAINCARCAREA OPERATORULUI DE INDEXARE [ ]// Memorarea unui sir in fisier f[0] = "CREARE
SIR"; cout<< "Dupamemorareasiruluiprimii25 bytes = " << '\n'; for(i=0; i<25; i++) {c = f[i]; cout<< c; }
cout<< '\n'; }

Supraincarcareaoperatorilor

15

1. Moduride supraincarcarea operatorilor2. Restrictiila supraincarcareaoperatorilor3.


Supraincarcareaoperatorilorunari4. Membriiconstantiaiclasei5.
Supraincarcareaoperatorilorinsertorsiextractor6. Supraincarcareaoperatoruluide atribuire= 7.
Supraincarcareaoperatoruluide indexare[ ] 8. Supraincarcareaoperatorilornew sidelete9.
Supraincarcareaoperatorului( ) 10.Supraincarcarea operatorului-> 11.ConversiiCAP. 2

Supraincarcareaoperatorilor

16

CAP. 3

3.8. SUPRAINCARCAREA OPERATORILOR NEWsiDELETE

Avantajulalocăriidinamiceamemorieişiaeliberăriiacesteiacuajutoruloperatorilornewşidelete,faţădeutiliza
reafuncţiilormalloc,callocsaufree,constăînfaptulcăoperatoriialocă(eliberează)memoriepentruobiecte,dat
edetipabstract.Acestlucruesteposibildeoareceaceştioperatoriauosupraîncărcareglobală,standard.

Supraincarcareaoperatorilor

17

CAP. 3

3.8. SUPRAINCARCAREA OPERATORILOR NEWsiDELETE

În cazul în care supraîncărcarea standard este insuficientă, utilizatorul poate supraîncărca operatorii prin
metode (implicit!) statice. Pentru operatorul new, funcţia membră care supraîncarcă operatorul neware
prototipul: void * <nume_clasa>::operator new(size_t<lungime>);

Supraincarcareaoperatorilor

18

CAP. 3

3.8. SUPRAINCARCAREA OPERATORILOR NEWsiDELETE

Funcţia returnează un pointer generic a cărui valoare este

adresa de început a zonei de memorie alocate dinamic. Tipul size_teste definit în stdlib.h. La aplicarea
operatorului, nu se indică nici o valoare pentru parametrul lungime (mărimea zonei de memorie
necesare obiectului pentru care se alocă dinamic memorie), deoarece compilatorul o determină,
automat.

Supraincarcareaoperatorilor

19

CAP. 3

3.8. SUPRAINCARCAREA OPERATORILOR NEWsiDELETE

Moduldeutilizarealoperatoruluinew:<nume_clasa>*<p>=new<nume_clasa>;Sau:<nume_clasa>*<p>=ne
w<nume_clasa>(<p1>,<p2>,<p3>);

Supraincarcareaoperatorilor
20

CAP. 3

3.8. SUPRAINCARCAREA OPERATORILOR NEWsiDELETE

Aplicareaoperatoruluinewsupraîncărcatdeutilizatordetermină,automat,apelulconstructoruluicorespunză
torclasei,saualconstructoruluiimplicit.<nume_clasa>*<p>=new<nume_clasa>;//apelconstrimplicitÎnadou
aformă,laalocareadinamicăamemorieiaparşiparametriiconstructorului(p1,p2,p3).<nume_clasa>*<p>=ne
w<nume_clasa>(<p1>,<p2>,<p3>);//apelconstrcuparametri

Supraincarcareaoperatorilor

21

CAP. 3

3.8. SUPRAINCARCAREA OPERATORILOR NEWsiDELETE

Operatoruldeletesesupraîncarcăprintr-ofuncţiemembrăcuprototipul:

void<nume_clasa>::operatordelete(void*);

Laaplicareaoperatoruluideleteseapelează,automat,destructorulclasei.

Supraincarcareaoperatorilor

22

CAP. 3

3.8. SUPRAINCARCAREA OPERATORILOR NEWsiDELETEExemplul 1:

Să urmărim exemplul următor, în care se supraîncarcă operatorii newşi delete. #include <iostream.h>
#include <stdlib.h> #include <string.h> #include <stddef.h> #include <conio.h> //
-------------supraincarcareaoperatoruluinew static void *operator new(size_tmarime, intnr_elem)
{ cout<< "\nOperatornew al programatorului!\n"; void *rtn= malloc(marime); if (rtn!= NULL)
memset(rtn, nr_elem, marime); return rtn; }

Supraincarcareaoperatorilor

23

CAP. 3

3.8. SUPRAINCARCAREA OPERATORILOR NEWsiDELETE//


-------------supraincarcareaoperatoruluideletevoid operator delete(void *tip) { cout << "\nOperator delete
al programatorului"; free(tip); } intmain() { // ------operatorulnew supraincarcatde programatorchar *cp=
new ('*') char[10]; // ----operatorulnew implicit int*ip= new int[10]; // -----release the memory (both use
our delete) delete ip; delete cp; getch(); }

Supraincarcareaoperatorilor

24
CAP. 3

3.8. SUPRAINCARCAREA OPERATORILOR NEWsiDELETEExemplul2:

class c1 { double n1, n2; public: c1(){n1=0; n2=0;} }; //. . . . intmain( ) { c1 *pc1=new c1; //se alocă
memorie pentru păstrarea unui obiect de tip c1 c1 *pc2=new c1(7, 5); //odată cu alocarea dinamică, se
realizează şi iniţializarea }

Supraincarcareaoperatorilor

25

CAP. 3

3.8. SUPRAINCARCAREA OPERATORILOR NEWsiDELETEExemplul3:

class c1{ double n1, n2; public: c1(){n1=0; n2=0;} c1(double x, double y) {n1=x; n2=y;} }; intmain( ) { c1
*pct1; pct1=new c1[100]; /*Se rezervă memorie ptr. 100 obiecte de tip c1. Se apelează constructorul
implicit de 100 de ori */ } Operatorii new, deletepermit alocarea dinamică şi pentru tablouri. În aceste
situaţii, se utilizează întotdeauna operatorii supraîncărcaţi global predefiniţi şi se apelează constructorul
fără parametri (dacă acesta există).

Supraincarcareaoperatorilor

26

CAP. 3

3.8. SUPRAINCARCAREA OPERATORILOR NEWsiDELETEExemplul4:

#include <iostream.h> class numar{ double *n; public: număr (double nr1); ~număr(); double val()
{return *n;} }; număr::număr(double nr1) {n=new double(nr1);} număr::~număr() { delete n;} intmain()
{număr a(7.53),b(2.14); număr *p1,*p2; p1=new număr(-1.74); cout<<p1<<'\n'; cout<<&p1<<'\n';
*p1=a; cout<<"p1="<<p1<<'\n'; delete p1; }

Supraincarcareaoperatorilor

27

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

28

CAP. 3

3.9. SUPRAINCARCAREA OPERATORULUI


()

Operatorul“apeldefuncţie”,utilizatsubforma

<nume> (<lista_param_efectivi>)

poatefiinterpretatcaooperaţiebinară,avândcaoperandstângnume,iarcaoperanddreptlista_param_efectivi
.Supraîncărcareaacestuioperatorbinar,nestatic,vapermiteutilizareasubforma:a(b,
…),sau(apelulexplicit):a.operator()(b,…).

Supraincarcareaoperatorilor

29

CAP. 3

3.9. SUPRAINCARCAREA OPERATORULUI ()

Avantajeleunuiastfeldeoperatorsunt:Evaluareaşiverificarealisteideargumenteînmodsimilaruneifuncţiiob
işnuite;Mecanismuluideapel:deşioperatorulestebinar,celde-
aldoileaoperandfiindolistădeargumente(chiarvidă),funcţiaoperatorpoateaveaoricâţiparametri.

Supraincarcareaoperatorilor

30

CAP. 3

3.9. SUPRAINCARCAREA OPERATORULUI ()

Încazulîncarenumelefuncţieiesteunpointercătreoanumităfuncţie(vezipointericătrefuncţii),apelulfuncţieis
erealizeazăprin:

(*<point_f>) (<lista_param_efectivi>);

Supraincarcareaoperatorilor

31

CAP. 3

3.9. SUPRAINCARCAREA OPERATORULUI ()

Funcţiacaresupraîncarcăoperatorultrebuiesăfiemetodănestatică.Supraîncărcareaoperatorului()seutilizea
zăînmodfrecventladefinireaaşa-
numituluiiterator.Iteratoriiseutilizeazăînlegăturăcutipuriabstractededate,careconţincolecţiideelemente(l
iste,arbori,tabelededispersie,etc.).

Supraincarcareaoperatorilor

32

CAP. 3

3.9. SUPRAINCARCAREA OPERATORULUI ()


Pe lângă protecţia datelor, iteratorii oferă un mijloc simplu de acces la elementele unei colecţii
(“traversarea” unei colecţiei), fără a intra în detaliile legate de implementarea colecţiei (independenţă a
utilizării unei colecţii şi implementării unei colecţii).În principiu, un iterator se implementează printr-o
clasă ataşată unui tip abstract care conţine o colecţie de elemente.

Supraincarcareaoperatorilor

33

CAP. 3

3.9. SUPRAINCARCAREA OPERATORULUI ()

Fie,deexemplu,clasacontainercareesteocolecţiedeobiectedetipoarecare,carepoatefiimplementatăcaunta
bloudeobiecte,caolistădenoduri,caunarborebinar,etc.Înfuncţiedeaceastăorganizare,clasacontainerconţin
eodatămembrădetipobiectsauunpointercătreobiectşiestecapabilsălivreze,perând,obiecteleelementealec
olecţiei.

Supraincarcareaoperatorilor

34

CAP. 3

3.9. SUPRAINCARCAREA OPERATORULUI ()Exemplu:

#include <iostream.h> #include <string.h> class Nume{ char nume[25]; public: Nume(char *s='\0')
{ strcpy(nume, s); } display() { cout<< '\n' << nume; } friend char * operator&(Nume& nm){ return
nm.nume; } void operator() (char *s) { strcpy(s, nume); } };

Supraincarcareaoperatorilor

35

CAP. 3

3.9. SUPRAINCARCAREA OPERATORULUI ()intmain() { Nume numes[10]; int n; cout<<"Nr nume=";


cin>>n; for (int i = 0; i < n; i++) {cout<< "\nIntrodunumele"<<i+1<<':'; cin>>&numes[i];} for (i = 0; i < 5; i+
+) cout << '\n' << &numes[i]; Numenm("VladMirela"); char newnume[25]; nm(newnume); //folosirea
operatorului () supraincarcat pentru a prelua valoarea unui nume cout<< newnume; }

Supraincarcareaoperatorilor

36

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
37

CAP. 3

3.10. SUPRAINCARCAREA OPERATORULUI ->

Supraîncărcareaoperatoruluiunar->(deselecţieindirectă,prinintermediulpointerului)serealizeazăprintr-
ometodănestatică.Expresia obiect -> expresie va fi interpretată ca (obiect.operator->())->expresie.
Deaceea,funcţiacaresupraîncarcăoperatorultrebuiesăreturnezefieunpointerlaunobiectalclasei,fieunobiec
tdeuntippentrucareestesupraîncărcatoperatorul->.

Supraincarcareaoperatorilor

38

CAP. 3

3.10. SUPRAINCARCAREA OPERATORULUI ->Exemplu:

#include <iostream.h> typedefstructex{ intmembru; }; class ex1{ ex *pointer; public: void set(ex &p)
{pointer=&p;} ex * operator -> (void) {return pointer;} }; class ex2{ ex1 *pointer; public: void set(ex1 &p)
{pointer=&p;} ex1 * operator -> (void) {return pointer;} }; intmain() {ex A; ex1 B; ex2 C; B.set(A); B-
>membru=10; //apelal funcţieiex1::operator->() cout<<B->membru<<'\n'; }

Supraincarcareaoperatorilor

39

CAP. 3

3.10. SUPRAINCARCAREA OPERATORULUI ->v. clasamatriceptexm

Supraincarcareaoperatorilor

40

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

41

CAP. 3

3.11. CONVERSII

Există următoarele tipuri de conversii: Conversiiimplicite; Conversiiexplicite.

Supraincarcareaoperatorilor
42

CAP. 3

3.11. CONVERSII

Conversiileimpliciteaulocînurmătoarelesituaţii:Încazulaplicăriioperatoruluideatribuire:operanduldrepte
steconvertitlatipuloperanduluistâng.Laapeluluneifuncţii:Dacătipulparametrilorefectivi(deapel)diferăde
tipulparametrilorformali,seîncearcăconversiatipuluiparametrilorefectivilatipulparametrilorformali.Lare
venireadintr-
ofuncţie:Dacăfuncţiareturneazăovaloareînprogramulapelant,laîntâlnireainstrucţiuniireturnexpresie;seînc
earcăconversiatipuluiexpresieilatipulspecificatînantetulfuncţiei.

Supraincarcareaoperatorilor

43

CAP. 3

3.11. CONVERSII

Conversiileexplicitepotfi:a)tip_predefinit_1->tip_predefinit_2b)tip_predefinit-
>tip_definit_de_utilizator(clasă)c)clasă->tip_predefinitd)clasă_1->clasă_2

Supraincarcareaoperatorilor

44

CAP. 3

3.11. CONVERSII

3.11.1. CONVERSII DIN TIP PREDEFINIT1ÎN TIP PREDEFINIT2

Pentrurealizareaunorastfeldeconversii,sefoloseşteoperatorulunardeconversieexplicită(cast),deforma:

(<tip>) <operand>

Exemplu:

intk; double x; x = (double) k / (k+1); /* În situaţia în care se doreşte obţinerea rezultatului real al
împărţirii întregului k la k+1, trebuie realizată o conversie explicită */ ÎnlimbajulC++ acelaşiefectse
poateobţineşiastfel: X = double (k) / (k+1); deoarece se apelează explicit constructorul tipului double.

Supraincarcareaoperatorilor

45

CAP. 3

3.11. CONVERSII

3.11.1. CONVERSII DIN TIP PREDEFINIT1ÎN TIP PREDEFINIT2


Exemplu:

#include <iostream.h>intmain (){intk=2; double x=4.5;x = (double) k / (k+1);cout<<x<<endl;x = k /


(k+1);cout<<x<<endl;x = double (k) / (k+1);cout<<x<<endl;}

Supraincarcareaoperatorilor

46

CAP. 3

3.11. CONVERSII

3.11.2. CONVERSII DIN TIP PREDEFINIT ÎN CLASA

Astfeldeconversiisepotrealizaatâtimplicit,câtşiexplicit,încazulîncarepentruclasarespectivăexistăunconstru
ctorcuparametriimpliciţi,detipulpredefinit.

Exemplu:

Pentruclasafracţiedefinităîncursurileanterioare,definireaunuiconstructorcuparametridetipint,vapermiter
ealizareaunorconversiiimplicitesauexpliciteint->fractie:

Supraincarcareaoperatorilor

47

CAP. 3

3.11. CONVERSII

3.11.2. CONVERSII DIN TIP PREDEFINIT ÎN CLASA

class fracţie{ intnrt, nmt; public: fracţie( intnrt= 0, intnmt= 1); // . . . }; intmain() {fractief; f = 20; /*
ConversieIMPLICITĂ: înainteaatribuiriise converteşteoperanduldrept(de tip int) la
tipuloperanduluistâng(tip fracţie). */ f = fractie(20); /*ConversieEXPLICITĂ: se converteşteîntregul20
într-un obiectal claseifracţie(nrt=20 şinmt=1). */ }

Supraincarcareaoperatorilor

48

CAP. 3

3.11. CONVERSII

3.11.2. CONVERSII DIN CLASAÎN TIP PREDEFINIT

Acesttipdeconversieserealizeazăprintr-
unoperatorspecial(cast)careconverteşteobiectuldinclasălatipulpredefinit.Operatoruldeconversieexplicită
sesupraîncarcăprintr-ofuncţiemembrănestatică.

<nume_clasa>:: operator <nume_tip_predefinit>( );


Laapelareaoperatoruluisefoloseşteunadinconstrucţiile:(<nume_tip_predefinit>)<obiect>;
<nume_tip_predefinit> (<obiect>);

Supraincarcareaoperatorilor

49

CAP. 3

3.11. CONVERSII

3.11.2. CONVERSII DIN TIP PREDEFINIT ÎN CLASA

Exemplul1:Pentruclasafracţie,săsesupraîncarceoperatorulde

conversieexplicită,caresărealizezeconversiifracţie-
>int.#include<iostream.h>classfracţie{longnrt,nmt;public:fracţie(intn=0,intm=1)
{nrt=n;nmt=m;}friendostream&operator<<(ostream&,constfracţie&);operatorint()
{returnnrt/nmt;}//conversiefracţie->int};

Supraincarcareaoperatorilor

50

CAP. 3

3.11. CONVERSII

3.11.2. CONVERSII DIN TIP PREDEFINIT ÎN CLASA

ostream&operator<<(ostream&ies,constfracţie&f)
{ies<<'('<<f.nrt<<'/'<<f.nmt<<")\n";returnies;}intmain()
{fracţiea(5,4),b(3),c;inti=7,j=14;c=a;c=7;cout<<(fracţie)243<<'\n';cout<<"(int)a="<<(int)a<<'\n';//conversi
eexplicităcout<<"int(a)="<<int(a)<<'\n';//conversieexplicităintx=a;//conversiasefaceimplicit,înaintedeatri
buire}

Supraincarcareaoperatorilor

51

CAP. 3

3.11. CONVERSII

3.11.2. CONVERSII DIN TIP PREDEFINIT ÎN CLASA

Exemplul 2:Pentru clasa Data se supraîncarcă operatorul

de conversie în long. #include <iostream.h> #include <conio.h> #include <time.h> class Data { intluna, zi,
an; public: Data() {} // constructor nulData(intl, intz, inta) { luna = l; zi = z; an = a; } Data(time_t); //
constructor de conversieoperator long(); // operator de conversieData->long void afisare(void); };

Supraincarcareaoperatorilor
52

CAP. 3

3.11. CONVERSII

3.11.2. CONVERSII DIN TIP PREDEFINIT ÎN CLASA

void Data::afisare() { cout<<"Data="<< luna<< '/' << zi<< '/' << an<<'\n'; } Data::Data(time_tacum)
{ structtm *tim= localtime(&acum); zi= tim->tm_mday; luna= tim->tm_mon+ 1; if (tim->tm_year>=2000)
an=tim->tm_year-100; //pentruanul>=2000 else an=tim->tm_year; /*tm_year=anuldin data -1900*/}

Supraincarcareaoperatorilor

53

CAP. 3

3.11. CONVERSII

3.11.2. CONVERSII DIN TIP PREDEFINIT ÎN CLASA

Data::operator long() { static intzil[]={31,28,31,30,31,30,31,31,30,31,30,31}; long zile = an; zile *= 365;


zile += an / 4; for (int i = 0; i < luna-1; i++) zile += zil[i]; zile+= zi; return zile; } intmain() { time_tacum=
time(NULL); Data dt(acum); dt.afisare(); Data xmas(12, 25, 89); xmas.afisare(); long d=xmas;
cout<<”Conversieexplicita:”<<(long)xmas; cout<<'\n'<< d; getch(); }

Supraincarcareaoperatorilor

54

CAP. 3

3.11. CONVERSII

3.11.2. CONVERSII DIN CLASA1ÎN CLASA2

Conversiadintip_abstract_1întip_abstract_2(dinclasă1înclasă2),serealizeazăcuajutorulunuiconstructoral
clasei2,careprimeştecaparametriobiectedinclasa1(fracţie->complex).

Supraincarcareaoperatorilor

55

CAP. 3

3.11. CONVERSII

3.11.2. CONVERSII DIN CLASA1ÎN CLASA2

Exemplul1:

#include <iostream.h> class fracţie{ intnrt, nmt; public: fracţie(int nr=0, int nm=1) {nrt=nr; nmt=nm;}
operator int() const//conversiefracţie-> int{return nrt/nmt;} friend ostream&operator<<(ostream&,
constfracţie&); friend class complex; /*cls. complex esteclasaprietenaptr. clasafracţie, fiecarefuncţiedin
complex esteprietenapentrufracţie*/ intîntreg() {return nrt/nmt;} };

Supraincarcareaoperatorilor

56

CAP. 3

3.11. CONVERSII

3.11.2. CONVERSII DIN CLASA1ÎN CLASA2

ostream&operator <<(ostream&ostr, constfracţie&f) {ostr<<'('<<f.nrt<<'/'<<f.nmt<<")\n";returnostr;}


class complex{ double re, im; public: complex (double r=0, double i=0) {re=r; im=i;} complex(fracţie&f) //
conversiefracţie->complex{re=(double)f.nrt/f.nmt; im=0;} operator double() const//conversiecomplex-
>double {return re;} friend ostream&operator<<(ostream&, constcomplex &); };
ostream&operator<<(ostream&ies, constcomplex &z) {ies<<'('<<z.re<<','<<z.im<<")=\n"; return ies;}

Supraincarcareaoperatorilor

57

CAP. 3

3.11. CONVERSII

3.11.2. CONVERSII DIN CLASA1ÎN CLASA2

intmain() { complex a(6.98, 3.2), b(9), c, d, e, q, s; int i=12, j=5, k;double x=1234.999, y=74.9897, u, z; c=i;
fractie r(7, 3), r1(9), t; d=x; //conversiedouble->complex(constructorcomplexcuarg. double)
e=complex(y,j); //apelexplicit al constr. complex; întâiconversiej de la intla double k=a;
//conversiecomplex->double->intu=a; //conversiecomplex->double

Supraincarcareaoperatorilor

58

CAP. 3

3.11. CONVERSII

3.11.2. CONVERSII DIN CLASA1ÎN CLASA2

z=(double)a/3; //conversiecomplex->double cout<<"r="<<r<<" q="<<q<<'\n'; cout<<"int(r)="<<int(r)<<"


(int)r="<<(int)r<<'\n'; //conversiefractie->intcout<<"r="<<r<<'\n'; cout<<r.intreg()<<'\n'; s=r; //
conversiefracţie->complex cout<<"(complex)r="<<(complex)r; cout<<" complex (r)="<<complex (r)<<'\n';
// conversiefracţie->complex }

59

CAP. 3Supraincarcareaoperatorilor
ÎNTREBĂRI 1. Cum se realizează conversia din clasă1 în clasă2? Daţi un exemplu. 2. Prin ce modalităţi se
pot supraîncărca operatorii? 3. Cum se realizează conversia din tip predefinit în clasă? În ce situaţii se
realizează conversiile implicite? 4. Ce restricţii impune mecanismul de supraîncărcare a operatorilor? 5.
Cum se poate realiza conversia dintr-un tip abstract (clasă) într-un tip predefinit? Exemplu. 6. Ce
observaţii puteţi face în legatură cu aritatea unui operator şi modul de supraîncărcare a acestuia? 7. În
cazul supraîncărcării metodelor, cum se poate realiza selecţia unei metode ?

60

CAP. 3

SFARSITUL Capitolului3

Supraincarcareaoperatorilor

PROGRAMAREACALCULATOARELORŞILIMBAJEDE PROGRAMAREII

1.Conceptede bazaale programariiorientate


peobiecte2.Clasesiobiecte3.Supraincarcareaoperatorilor4.Creareaierarhiilorde clase5.Operatiide intrare/
iesirein limbajulC++6.Implementariale modelelorde
date7.Functiisiclasegenerice8.ExceptiisitratareaacestoraCuprinsulCursului

Programareacalculatoarelorşilimbajede programareII

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