Sunteți pe pagina 1din 12

CAPITOLUL 2

Clasesiobiecte
(continuare)
3
Clasesiobiecte
4
1. Definitiaclaselor, accesla membri2. Instantiereaclaselor3. Membriiuneiclase4.
Pointerulthis5. Domeniulnumelui, vizibilitatesi timp de viata6. Functiiinline7.
Constructorisidestructori8. Tablouride obiecte9. Functiiprietene(friend)CAP. 2
CAP. 2
5
2.6 FunctiiinlineClasesiobiecte
La apelul unei functii obisnuite se �ntrerupe executia functiei apelante si se
executa un salt la adresa de memorie la care se gaseste corpul functiei apelate. La
terminarea executiei functiei apelate se revine �n functia apelanta, relu�ndu-se
executia cu instructiunea imediat urmatoare apelului de functie. �n situatiile �n
care corpul functiei apelate este format din c�teva instructiuni, operatiile
descrise anterior (implicate �n apel si revenire) pot fi mai complicate dec�t un
apel prin expandare (�n care apelul functiei �n functia apelanta este �nlocuit cu
�nsusi corpul functiei apelate). Pentru eliminarea acestor dezavantaje, se folosesc
functiileinline.
CAP. 2
6
2.6 FunctiiinlineClasesiobiecte
Prezenta functiilor inline anunta compilatorul sa nu mai genereze instructiunile �n
cod masina necesare apelului si revenirii, ceea ce conduce la marirea timpului de
compilare �n favoarea micsorarii timpului de executie.Utilizarea functiilor inline
se justifica doar �n situatiile �n care codul generat de compilator pentru executia
corpului functiei este mai mic dec�t codul generat pentru apel si revenire.
CAP. 2
7
2.6 FunctiiinlineClasesiobiecte
Practic, functiile care au corpul format din maximum trei
instructiunisi nu contin instructiuni repetitive (for, while, do-
while), pot fi declarate inline. Declararea unei functii inline se realizeaza
explicit, specific�nd �n antetul functiei respective cuv�ntul cheie inline.
inline <tip_val_ret> <nume_fct> (<lista_declar_par_formali>);
CAP. 2
8
2.6 FunctiiinlineClasesiobiecte
�n cazul metodelor unei clase, daca acestea sunt definite �n interiorul clasei, ele
sunt considerate, implicit, functii inline. Exista si posibilitatea de a declara
metoda la declararea
clasei si de a specifica, explicit, ca este functie inline la
definirea functiei.
CAP. 2
9
2.6 FunctiiinlineClasesiobiecte
Exemplu: Daca se doreste ca metoda seteaza_dim din exercitiul
anterior sa fie functie inline, fara a modifica declaratia tipului dreptunghi, se
poate proceda astfel: class dreptunghi{ // . . . public: // . . . void
seteaza_dimen(double, double );// declarareametodei// . . . }; inline void
dreptunghi::seteaza_dimen(double L, double l) //functieinline, explicit {Lung=L;
lat=l;} Prefixarea definitiei functiei seteaza_dimen cu cuv�ntul cheie inline este
echivalenta cu definirea metodei �n cadrul declaratiei clasei dreptunghi.
CAP. 2
10
2.6 FunctiiinlineClasesiobiecte
Exemplu:tipuldedatecomplex
Datelemembru:?partereala?parteimaginara.Operatiile:?
Citireauneidatedetipcomplex(citireaval.ptrpartearealasiceaimaginara);?
afisareauneidatedetipcomplex;?calcululmodululuiunuicomplex;?
calcululargumentuluiunuicomplex;?incrementareapartiiimaginare;?
decrementareapartiiimaginare;?
functiicarereturneazavaloareapartiirealesiapartiiimaginareauneidatedetipcomplex;?
adunareaadouadatedetipcomplex;?�nmulttireaadouadatedetipcomplex.
CAP. 2
11
2.6 FunctiiinlineClasesiobiecte
Exemplu: tipulde date complex
#include <iostream.h> #include <math.h> #define PI 3.14159 class complex{ double
real, imag; public: intcitire(); void afisare(); double modul(); double arg(); void
incrpi() /*incrementeaza partea imaginara; FUNCTIE INLINE, implicit, fiind definita
�n interiorul clasei */ { imag++;} inlinevoid decrpi(); //decrementarea partii
imaginare double retreal(); //returneazapartearealadouble retimag();
//returneazaparteaimaginaravoidadun_c(complex, complex); //aduna2 numerecomplexe
void inm_c(complex*, complex*); //produsula 2 numerecomplexe};
CAP. 2
12
2.6 FunctiiinlineClasesiobiecte
Exemplu: tipulde date complex
inlinedouble complex::modul(){ return
sqrt(real*real+imag*imag);}intcomplex::citire(){ cout<<"P. reala:"; if (!
(cin>>real)) return 0;cout<<"P. imag:";if (!(cin>>imag)) return 0 ; return 1; }
void complex::afisare(){ if (imag>=0) cout<<real<<"+"<<imag<<"*i"<<"\n";else
cout<<real<<imag<<"*i\n";}double complex::arg() {if (real==0 && imag==0) return
0.0;if (imag==0)//z=p. realaif (real>0) return 0.0;else return PI;if (real==0)if
(imag>0) return PI/2;else return (3*PI)/2;double x=atan(imag/real);if (real<0)
return PI+x;if (imag<0) return 2*PI+x; return x;}inlinevoid complex::decrpi()
{ imag--;}double complex::retreal() { return real;}
CAP. 2
13
2.6 FunctiiinlineClasesiobiecte
Exemplu: tipulde date complex
double complex::retimag(){ return imag; }void complex::adun_c(complex x1, complex
x2){real=x1.real+x2.real;imag=x1.imag+x2.imag;}void complex::inm_c(complex *x1,
complex *x2){real=x1->real*x2->real-x1->imag*x2->imag;imag=x1->real*x2->imag+x1-
>imag*x2->real;}intmain(){complex z1;z1.citire();cout<<"z1=";z1.afisare();complex
z2;z2.citire();cout<<"z2=";z2.afisare();cout<<"Modululz2="<<z2.modul()<<'\n';cout<<
"Agumentz2="<<z2.arg()<<'\n';cout<<"P. realaz2="<<z2.retreal();cout<<"P
imagz2="<<z2.retimag()<<'\n';z2.incrpi();cout<<"Dupaincremp
imag=";cout<<z2.retimag()<<'\n';z2.afisare();complex
z3;z3.adun_c(z1,z2);cout<<"Adunarez1+z2=";z3.afisare();complex*pz1=&z1,*pz2=&z2;z3.
inm_c(pz1,pz2);cout<<"Inmultirez1+z2=";z3.afisare();}
Clasesiobiecte
14
1. Definitiaclaselor, accesla membri2. Instantiereaclaselor3. Membriiuneiclase4.
Pointerulthis5. Domeniulnumelui, vizibilitatesi timp de viata6. Functiiinline7.
Constructorisidestructori8. Tablouride obiecte9. Functiiprietene(friend)CAP. 2
CAP. 2
15
2.7 ConstructorisidestructoriClasesiobiecte
Este indicat ca �n cazul �n care datele structurate au ca membrii pointeri, sa se
aloce memorie �n mod dinamic. 2.7.1. INITIALIZAREA DATELOR La declararea datelor de
tip predefinit sau definit de utilizator prin structuri, uniuni sau clase,
compilatorul aloca o zona de memorie corespunzatoare tipului respectiv.
CAP. 2
16
2.7 ConstructorisidestructoriClasesiobiecte
2.7.1. INITIALIZAREA DATELOR �n general, datele statice sunt initializate automat
cu valoarea 0. Celelalte categorii de date, nu sunt initializate. Initializarea
datelor simple de tip predefinit se poate realiza dupa declararea acestora, sau �n
momentul declararii. Exemple:
inti; i=30; // declarareavariabileii, apoiinitializareaeiprinatribuirechar
c='A'; // declarareasiinitializareavariabileic
CAP. 2
17
2.7 ConstructorisidestructoriClasesiobiecte
2.7.1. INITIALIZAREA DATELOR Initializarea datelor structurate se poate realiza �n
momentul declararii acestora, prin listele de initializare. Exemple:
//1 declarareasiinitializareavectoruluia inta[]={20, 30, 40, 50}; //2
declarareasiinitializareamatriciim double m[2][3]={{1.1,2.2,3.3},
{11.11,22.22,33.33}};//3 structpers{ char nume[20]; int varsta; double salariu; }
p={"Popescu", 20, 3000000};
CAP. 2
18
2.7 ConstructorisidestructoriClasesiobiecte
2.7.1. INITIALIZAREA DATELOR �n cazul tipurilor de date definite cu ajutorul
claselor, care au date membru private, listele de initializare nu pot fi utilizate.
Pentru a elimina aceste neajunsuri, limbajul C++ ofera mecanismul constructorilorsi
al desctructorilor.
CAP. 2
19
2.7 ConstructorisidestructoriClasesiobiecte
2.7.2. CONSTRUCTORIConstructoriisunt metodespeciale care folosesc la creareasi
initializareainstantelorunei clase. Constructoriiau acelasi nume ca si clasa careia
�i apartin si
sunt apelati de fiecare data c�nd se creaza noi instante ale clasei.
Constructoriiasigura initializarea corecta a tuturor variabilelor membre ale
obiectelor unei clase si constituie o garantie a
faptului ca initializarea unui obiect se realizeaza o singura data.
CAP. 2
20
2.7 ConstructorisidestructoriClasesiobiecte
2.7.2.
CONSTRUCTORIOclasapoateaveamaimulticonstructori,caredifera�ntreeiprinnumarulsitipul
parametriloracestora.AcestlucruesteposibildeoarecelimbajulC+
+permitesupradefinirea(overloading)functiilor.
CAP. 2
21
2.7 ConstructorisidestructoriClasesiobiecte
2.7.2.
CONSTRUCTORISupra�ncarcarea(supradefinirea)reprezintaposibilitateadeaatribuiunuinum
emaimultesemnificatii,caresuntselectate�nfunctiedecontext.Practic,sepotdefinifuncti
icuacelasinume,darculistedeparametridiferite,canumarsi/saucatipurideparametri.�nmom
entulapeluluifunctiei,selectareafunctieiadecvateseface�nurmacomparariitipurilorpara
metrilorefectivicutipurileparametrilorformali.Deaceea,declarareaunorfunctiicuacelas
inumesiacelasisetdeparametriesteilegalasiestesemnalatacaeroarelacompilare.
CAP. 2
22
2.7 ConstructorisidestructoriClasesiobiecte
2.7.2. CONSTRUCTORILa �nt�lnirea declaratiei unui obiect, se apeleaza automat un
constructor al clasei respective. La fiecare instantiere a clasei se aloca memorie
pentru datele membre. Deci pentru fiecare obiect declarat se aloca memorie pentru
datele membre ale clasei.Exceptie de la aceasta regula o constituie datele membru
statice. Acestea figureaza �ntr-un singur exemplar pentru toate instantele clasei
respective. Functiile membru exista �ntr-un singur exemplar pentru toate instantele
clasei. Ordinea �n care sunt apelati constructorii corespunde ordinii declararii
obiectelor.
CAP. 2
23
2.7 ConstructorisidestructoriClasesiobiecte
2.7.2. CONSTRUCTORIProprietatile constructorilor: �Constructorii au acelati nume ca
si numele clasei careia �i apartin; �Nu �ntorc nici o valoare (din corpul lor
lipseste intructiunea return <expr>; �n antetul constructorilor nu se specifica
niciodata -la tipul valorii returnate -cuv�ntul cheie void);
�Constructoriiuneiclasenu pot primicaparametriinstanteale claseirespective, ci
doarpointerisaureferintela instanteleclaseirespective; �Apelul constructorului se
realizeaza la declararea unui obiect; �Adresaconstructorilornueste
accesibilautilizatorului;
CAP. 2
24
2.7 ConstructorisidestructoriClasesiobiecte
2.7.2. CONSTRUCTORIProprietatile constructorilor: (continuare)�Constructorii nu pot
fi metode virtuale; ��n cazul �n care o clasa nuare nici constructor declarat de
catre programator, compilatorul genereaza un constructor implicit, fara nici un
parametru, cu lista instructiunilor vida. Daca exista un constructor al
programatorului, compilatorul nu mai genereaza constructorul implicit ; �Parametrii
unui constructor nu pot fi de tipul definit de clasa al carei membru este
constructorul.
CAP. 2
25
2.7 ConstructorisidestructoriClasesiobiecte
2.7.2. CONSTRUCTORIExemplul1: Pentruclasacomplex s-a definitun
constructor cu parametriimpliciti; din acestmotivs-a pututface declaratia"complex
z1;". �nultimaliniea programului, pentruobiectulz4, constructorulesteapelat�nmod
explicit. class complex { double real,imag; public: complex(double x=0, double
y=0); // Constructor implicit}; complex::complex(double x, double y) {real=x;
imag=y; } main() {complex z1; //z1.real=0, z1.imag=0 complex z2(1); //z2.real=1,
z2.imag=0 complex z3(2,4); //z3.real=2, z3.imag=4 complex z4=complex();
//apelexplicit al constructorului}
La apelulexplicit al constructorului: complex z4=complex();
Evaluareaexpresieicomplex() conduce la: ?Crearea unui obiect temporar de tip punct
(obiect cu o adresa precisa, dar inaccesibil); ?
Apelulconstructoruluipentruacestobiecttemporar; ?Copiereaacestuiobiecttemporar�nz4.

CAP. 2
26
2.7 ConstructorisidestructoriClasesiobiecte
2.7.2. CONSTRUCTORIExemplul2: Pentru clasa complex exista un constructor
explicit, compilatorul nu mai creeaza unul implicit. class complex { double
real,imag; public: complex(double x,doubley) // functieconstructorinline{ real=x;
imag=y;} }; intmain() {complex z1(2,3); complex z; // Eroare : nu exista
constructor implicit }
CAP. 2
27
2.7 ConstructorisidestructoriClasesiobiecte
2.7.2. CONSTRUCTORIExemplul3: Definireaunuiconstructor implicit vid, care se va
apelala instantiereaobiectelorneinitializate. #include<iostream.h> class
data{ intzi,luna,an; public: data() { } // constructor implicit vid data(int z,int
l,int a) // constructor cu parametri { zi=z;luna=l;an=a; } }; intmain() {data d; //
apelul constructorului vid data d1(12,11,1998); // apelul constructorului cu
parametri }
CAP. 2
28
2.7 ConstructorisidestructoriClasesiobiecte
2.7.2.1 Constructoricu listede initializare�n exemplele anterioare, constructorii
initializau membrii unui obiect prin atribuiri. Exista si modalitatea de a
initializa membrii printr-o lista de instantiere (initializare), care apare �n
implementarea constructorului, �ntre antetul si corpul acestuia. Lista contine
operatorul
:
, urmat de numele fiecarui membru si valoarea de initializare, �n ordinea �n care
membrii apar �n definitia clasei.
CAP. 2
29
2.7 ConstructorisidestructoriClasesiobiecte
2.7.2.1 Constructoricu listede initializareExemplul1:Pentruclasacomplexs-
aimplementatunconstructorde
initializareculistadeinstantiere.classcomplex{doublereal,imag;public:complex(double
x,doubley);//constructor};complex::complex(doublex,doubley):real(x),imag(y)//Listad
einitializareamembrilor{return;}intmain()
{complexz1(1,3),z2(2,3);}/////////////////Sau:classcomplex{doublereal,imag;public:c
omplex(doublex,doubley):real(x),imag(y){}//constructorculistadeinitializare};
CAP. 2
30
2.7 ConstructorisidestructoriClasesiobiecte
2.7.2.2 Constructoride copierePentru o clasa, se poate defini un contructor de
copiere, care sa permita copierea obiectelor. Deoarece parametrii unui constructor
nu pot fi de tipul definit de clasa al carei membru este, constructorul de copiere
pentru clasa cu numele cls, are, de obicei, prototipul:
cls<cls> (const<cls> &);
CAP. 2
31
2.7 ConstructorisidestructoriClasesiobiecte
2.7.2.2 Constructoride copiereParametrul transmis prin referinta este obiectul a
carui copiere se realizeaza, modificatorul de acces constinterzic�nd modificarea
acestuia. Constructorul de copiere poate avea si alti parametri, care trebuie sa
fie impliciti. Daca programatorul nu defineste un constructor de copiere,
compilatorul genereaza un asemenea constructor, implicit. �n situatiile �n care un
tip de date are ca membrii pointeri, este necesara implementarea unui constructor
pentru initializare (este de dorit sa se aloce dinamic memorie) si a unui
constructor de copiere.
CAP. 2
32
2.7 ConstructorisidestructoriClasesiobiecte
2.7.2.2 Constructoride copiereExemplu: Exemplul urmator, �n care se definesc
tipurile de date Punct si
Linie, ilustreaza utilizarea constructorilor (cu parametri impliciti, de copiere,
cu liste de initializare) definiti de programator. #include <iostream.h> class
Punct{public: Punct(double _x=0.0, double _y=0.0)//
Constructorcuparametriimpliciti{ x = _x; y = _y; } Punct(constPunct& p) { x = p.x,
y = p.y;} //Constructor de copierevoid afiseaza(); // Metodaafiseazaprivate:double
x, y; // Datelemembreprivate (coodonatelepunctului: abscisasiordonata)};
CAP. 2
33
2.7 ConstructorisidestructoriClasesiobiecte
2.7.2.2 Constructoride copiereclass Linie{public: Linie(constPunct& b, Punct& e) :
p1(b), p2(e) {} //Constructor cu listainitializarevoid afiseaza(); private: Punct
p1, p2; //Datele membre private: cele 2 puncte care determina dreapta }; void
Punct::afiseaza() { cout<< "(" << x << " , " << y << ")"; } void Linie::afiseaza()
{ cout<< "Liniedeterminatade punctele: "; p1.afiseaza(); p2.afiseaza(); cout<<�\n�;
} intmain() { Puncta=(10.,15.), b=(20.,30.); a.afiseaza(); b.afiseaza();
Liniel1(a,b); l1.afiseaza(); }
CAP. 2
34
2.7 ConstructorisidestructoriClasesiobiecte
2.7.3 DestructoriDestructoriisunt metode ale claselor care actioneaza �n sens
invers, complementar, fata de constructori. Constructorii sunt folositi pentru
alocarea memoriei, initializarea datelor membru sau alte operatii (cum ar fi,
incrementarea unui contor pentru instantele clasei). Constructorul este apelat �n
momentul declararii obiectelor. Destructorul elibereaza memoria alocata de
constructori. Destructorul este apelat automat, la iesirea din blocul �n care este
recunoscut acel obiect.
CAP. 2
35
2.7 ConstructorisidestructoriClasesiobiecte
2.7.3 DestructoriProprietatile destructorilor �Destructorul are acelasi nume ca si
clasa a caror metoda este; �Numeledestructoruluiesteprecedatde semnul
~
; �O clasaare un singurdestructor;
�Destructorul nu are parametri si nu returneaza nici o valoare (antetul nu contine
cuv�ntul cheie void, iar �n corpul destructorului nu apare instructiunea return
<expresie>;); �Daca programatorul nu a definit un destructor, compilatorul
genereaza automat un destructor pentru clasa respectiva;
�Destructorii se apeleaza la �ncheierea timpului de viata a obiectelor, �n ordine
inversa apelurilor constructorilor; �Obiecteledinamicenu se distrugautomat,
deoarecedoarprogramatorulstiec�ndnu maiestenecesarun astfelde obiect.
CAP. 2
36
2.7 ConstructorisidestructoriClasesiobiecte
2.7.3 DestructoriExercitiul 1: Se defineste tipul de date Timp, care implementeaza
un cronometru
care masoara timpul scurs �ntre 2 evenimente (evenimente date de apelul
constructorului si al destructorului). Se foloseste functia clock din ANSI C. /*
fisierul timp.h, cu definirea clasei */ #if !defined(__TIMP_H) #define __TIMP_H
#include <time.h> // definestetipulclock_tsiCLK_TCK #include <iostream.h> class
Timp{public: Timp() { start = clock();} // Constructor ~Timp() // Destructor
(calculeazasiafiseazatimpul, in secunde) { clock_tstop = clock(); cout<< "Timpul=
"; cout<< (stop -start)/CLK_TCK; cout<< " secunde" << �\n�; } private:
clock_tstart; // pornestemasurareatimpului}; #endifClasa Timp are data membru
privata start (de tipul clock_t), constructor si destructor.
CAP. 2
37
2.7 ConstructorisidestructoriClasesiobiecte
2.7.3 Destructori/* fisierulde test, timptest.cpp, in care se utilizeazatipulde
date Timp*/ #include "timp.h" static void functie(unsigned long cont) { Timpt; //
Declarareaobiectuluit, de tip Timpfor(unsigned long i = 0; i < cont; i++) { double
a = (double)(i-1); double b = (double)(i+1); double c = (double)(i+i); double d =
a*b -c; } } intmain() { unsigned long val_cont; cout<< "Valoarefinala: "; cin>>
val_cont; functie(val_cont); }
Se executa prelucrarile din corpul functiei (calculul valorilor variabilelor a, b,
c si d pentru fiecare valoare a contorului i). La iesirea din functie, este apelat
destructorul (definit de programator) clasei Timp (se distruge obiectul t,
variabila locala functiei). Astfel, �n variabila stop, variabila locala
destructorului, se memoreaza valoarea returnata de functia clock (deci timpul
momentului de �ncheiere a executiei corpului functiei functie). Diferenta �ntre
cele 2 evenimente (�nceputul executiei corpului functiei functie si sf�rsitul
acesteia) este transformata �n secunde si afisata.
CAP. 2
38
2.7 ConstructorisidestructoriClasesiobiecte
2.7.3 DestructoriExercitiul2:
Sa se defineasca tipul punct, cu datele membre x si y, reprezent�nd abscisa si
ordonata unui punct. Operatiilecare pot fi realizate asupra obiectelor de tip
punct, sunt: �afisare (afiseaza coordonatele unui punct), �deplasare (deplaseaza un
punct, noile coordonate ale punctului fiind obtinute prin adunarea unor valori
transmise ca parametri, la valorile anterioare ale coordonatelor), �abscisa
(returneaza valoarea abscisei), �ordonata (returneaza valoarea ordonatei). Se vor
implementa, deasemenea, constructor cu parametri impliciti, constructor av�nd ca
parametri valorile abscisei si a ordonatei, constructor de copiere si destructor.
CAP. 2
39
2.7 ConstructorisidestructoriClasesiobiecte
#include <iostream.h> #include <stdlib.h> #include <stdio.h> #include <conio.h>
//CLASA PUNCT class punct{ double x,y; public: punct() {x=0;y=0; cout<<"Constr.
implicitpentrupunct("<<x<<","<<y<<")\n";} punct(double,double); //constructor
initializarepunct(punct&); //constructor copiere~punct(); //destructor double
abscisa(){return x;} double ordonata(){return y;} void afisare(); void
deplasare(double,double); };
CAP. 2
40
2.7 ConstructorisidestructoriClasesiobiecte
2.7.3 DestructoriSa se defineasca tipul segment, cu datele membre A si B, de tip
punct, reprezent�nd capetele unui segment (originea si v�rful). Operatiilecare pot
fi realizate asupra obiectelor de tip segment, sunt: �afisare (afiseaza
coordonatele capetellor segmentului),�deplasare (translateaza un segment, deplas�nd
capetele acestuia cu valorile transmise ca parametri), �origine (returneaza
originea segmentului), v�rf (returneaza v�rful segmentului). Se vor implementa,
deasemenea, constructor, constructor de copiere si destructor. Sase
testezetipurilede date punctsisegment.
CAP. 2
41
2.7 ConstructorisidestructoriClasesiobiecte
2.7.3 Destructori//CLASA SEGMENT class segment {private: punctA,B; public:
segment(punct&,punct&); //constructor segment(segment&); //constructor
copiere~segment(); //destructor punctorigine(); punctvarf(); void afisare(); void
translatie(double,double); };
CAP. 2
42
2.7 ConstructorisidestructoriClasesiobiecte
2.7.3 Destructori//METODELE CLASEI PUNCT punct::punct(double valx,doublevaly)
{ x=valx;y=valy;cout<<"Constructor punct("<<x<<","<<y<<")\n";} punct::~punct()
{cout<<"Destructor punct("<<x<<","<<y<<")\n";} punct::punct( punct&P)
{x=P.x;y=P.y;cout<<"Constructor copiere"; cout<<" pct("<<x<<","<<y<<")\n";}
voidpunct::deplasare(double dx,doubledy) {x+=dx; y+=dy;} void punct::afisare()
{ cout<<"Punct("<<x<<','<<y<<')';}
CAP. 2
43
2.7 ConstructorisidestructoriClasesiobiecte
//METODELE CLASEI SEGMENT segment::segment(punct&A1,punct &B1)
{ A=A1;B=B1;cout<<"Constructor segment["; A.afisare();B.afisare();cout<<"]\n";}
segment::segment(segment &AB) { A=AB.A; B=AB.B; cout<<"Constructor copieresegment
["; A.afisare(); B.afisare();cout<<"]\n";} punctsegment::origine() { return A;}
punctsegment::varf() { return B;} void segment::afisare()
{cout<<"[";A.afisare();cout<<','; B.afisare();cout<<"]"<<'\n';} segment::~segment()
{ cout<<"Destructor segment [";A.afisare(); cout<<",";B.afisare(); cout<<"]\n";}
voidsegment::translatie(double dx,doubledy) { A.deplasare(dx,dy);
B.deplasare(dx,dy);}
CAP. 2
44
2.7 ConstructorisidestructoriClasesiobiecte
2.7.3 Destructoriintmain() { punctP(7.8,-20.4),Q(-4.82,8.897),A,B; /*Constructor
punct(7.8,-20.4) (PentrupunctulP) Constructor punct(-4.82,8.897) (PentrupunctulQ)
Constr. implicit pentrupunct(0,0) Constr. implicit pentrupunct(0,0)
(pentrupuncteleA, B)*/ punctP3, Q3; /* Constr. implicit pentrupunct(0,0)Constr.
implicit pentrupunct(0,0) (pentrupuncteleP3, Q3) */ segment S(P,Q); /* Constr.
implicitpentrupunct(0,0)Constr. implicitpentrupunct(0,0) (pentrumembriiA, B
aiobiectuluiS, decipentruS.A siS.B)
1
CAP. 2
45
2.7 ConstructorisidestructoriClasesiobiecte
2.7.3 DestructoriConstructor segment[Punct(7.8,-20.4)Punct(-4.82,8.897)]
(pentruobiectulS, de tip segment) */ segment S1(P3,Q3); /* Constr. implicit
pentrupunct(0,0) Constr. implicit pentrupunct(0,0) (pentrumembriiA, B
aiobiectuluiS1, decipentruS1.A siS1.B) Constructor segment[Punct(0,0)Punct(0,0)]
(pentruobiectulS1, de tip segment) */ printf("Apasa un car. ptr. continuare!\n");
getch(); cout<<"Punctele:\n"; P.afisare();cout<<'\n'; Q.afisare();cout<<'\n';
P3.afisare();cout<<'\n'; Q3.afisare();cout<<'\n'; A.afisare(); cout<<'\n';
B.afisare();cout<<'\n'; cout<<"\nSegment:"; S.afisare(); cout<<'\n';
/
CAP. 2
46
2.7 ConstructorisidestructoriClasesiobiecte
2.7.3 Destructori/* Punctele: Punct(7.8,-20.4) (pentruobiectulP) Punct(-4.82,8.897)
(pentruobiectulQ) Punct (0,0) (pentru obiectul A) Punct (0,0) (pentru obiectul B)
Punct(0,0) (pentruobiectulP3) Punct(0,0) (pentruobiectulQ3) Segment:[Punct(7.8,-
20.4),Punct(-4.82,8.897)] */ punctD(1,2); punctC; // Constructor punct(1,2)Constr.
implicit pentrupunct(0,0) (pentrupuncteleD, C) C=D; //operatiede
atribuireC.afisare(); // Punct(1,2) (pentrupunctulC) getch();
CAP. 2
47
2.7 ConstructorisidestructoriClasesiobiecte
2.7.3 DestructoripunctCC=C; // Constructor copierepct(1,2) cout<<"In urma
copierii:"; CC.afisare(); // �nurmacopierii:Punct(1,2) (pentrupunctulCC) cout<<"Se
deplaseazapunctulCC cu valorile10, 20. Noilecoord.="; CC.deplasare(10, 20);
CC.afisare(); // Se deplaseazapunctulCC cu valorile10, 20. Noilecoord.=Punct(11,22)
cout<<"AbscisaCC="<<CC.abscisa(); cout<<" Ordonata CC="<<CC.ordonata()<<'\n';
//AbscisaCC=11 OrdonataCC=22 cout<<"Varfsegment S="; (S.varf()).afisare(); /*
Varfsegment S=Constructor copierepct(-4.82,8.897) (metodavarfreturneazaun punct,
copiere) Punct(-4.82, 8.897) Destructor punct(-4.82,8.897) */
CAP. 2
48
2.7 ConstructorisidestructoriClasesiobiecte
2.7.3 Destructoricout<<"Origine segment S="; CC=S.origine(); /* Originesegment
S=Constructor copierepct(7.8,-20.4) (metodaoriginereturneazaun punct, copiere)
Destructor punct(7.8,-20.4) */ CC.afisare(); // Punct(-4.82, 8.897) S1=S;
//operatiede atribuireS1.afisare(); // Punct (7.8,-20.4)[Punct (7.8,-20.4),Punct (-
4.82,8.897)] cout<<"TranslatieS1 cu 100,1000. S1 translatateste:";
S1.translatie(100, 1000); S1.afisare(); /* TranslatieS1 cu 100,1000. S1
translatateste:[Punct(107.8,979.6),Punct(95.18,1008.897)] */
CAP. 2
49
2.7 ConstructorisidestructoriClasesiobiecte
2.7.3 Destructorisegment S2=S1; /* Constr. implicit pentru punct(0,0) (pentru S2.A)
Constr. implicit pentrupunct(0,0) (pentruS2.B) Constructor copieresegment
[Punct(107.8,979.6)Punct(95.18,1008.897)] Destructor segment
[Punct(107.8,979.6),Punct(95.18,1008.897)]*/ cout<<"Segment S2
obtinutprincopiere:"; S2.afisare(); // Segment S2 obtinutprincopiere:
[Punct(107.8,979.6),Punct(95.18,1008.897)] cout<<"Iesiredinmain\n"; //
Iesiredinmain }
CAP. 2
50
2.7 ConstructorisidestructoriClasesiobiecte
2.7.3 Destructori/* La iesirea din functia main, deci la terminarea duratei de
viata a obiectelor, se apeleaza automat destructorii, �n ordinea inversa �n care au
fost apelati constructorii, astfel: Destructor segment
[Punct(107.8,979.6),Punct(95.18,1008.897)] (pentrusegmentulS2) Destructor punct
(95.18,1008.897) (pentru membrii B, respectiv A, ai segmentului S2: S2.B, apoi
S2.A) Destructor punct(107.8,979.6) Destructor punct(7.8,-20.4) (pentruCC)
Destructor punct(1,2) (pentruC) Destructor punct(1,2) (pentruD) Destructor segment
[Punct(107.8,979.6),Punct(95.18,1008.897)] (pentrusegmentulS1) Destructor punct
(95.18,1008.897) (pentru membrii B, respectiv A, ai segmentului S1: S1.B, apoi
S1.A) Destructor punct(107.8,979.6)
CAP. 2
51
2.7 ConstructorisidestructoriClasesiobiecte
2.7.3 DestructoriDestructor segment [Punct(7.8,-20.4),Punct(-4.82,8.897)]
(pentrusegmentulS) Destructor punct (-4.82,8.897) (pentru membrii B, respectiv A,
ai segmentului S: S.B, apoi S.A) Destructor punct(7.8,-20.4) Destructor punct(0,0)
(pentrupunctulQ3) Destructor punct(0,0) (pentrupunctulP3) Destructor punct(0,0)
(pentrupunctulB) Destructor punct(0,0) (pentrupunctulA) Destructor punct(-
4.82,8.897) (pentrupunctulQ) Destructor punct(7.8,-20.4) (pentrupunctulP) */
CAP. 2
52
2.7 ConstructorisidestructoriClasesiobiecte
2.7.3 DestructoriExercitiul evidentiaza urmatoarele probleme: 1. �n situatia �n
care o clasa C1 are ca date membre obiecte ale altei clase C2 (clasa segment are ca
date membre obiecte de tipul punct), la construirea unui obiect din C1, se apeleaza
�nt�i constructorul C2 pentru membrii (de tip C2), apoi constructorul C1. Un astfel
de exemplu �l constituie declararea segmentului S: segment S(P,Q); Se apeleaza
�nt�i constructorul implicit al clasei punct pentru membrii A si B ai segmentului S
(deci pentru S.A si S.B), apoi constructorul clasei segment (figura). La
distrugerea obiectului din clasa C1, destructorii sunt apelati �n ordinea inversa
constructorilor (�nt�i se apeleaza destructorul clasei segment -�nvelisul exterior,
apoi destructorul pentru membrii de tip punct).
CAP. 2
53
2.7 ConstructorisidestructoriClasesiobiecte
2.7.3 Destructori2. Sa revedem secventa: punct D(1,2); punct C; C=D; �n acest caz,
se realizeaza o atribuire, membru cu membru, echivalenta cu: C.x=D.xsiC.y=D.y. 3.
Sa revedem secventa: punctCC=C; �n acest caz, se apeleaza constructorul de copiere,
care creaza punctul CC prin copierea punctului C. Apelul constructorului de copiere
se poate realiza si explicit: punctCC=punct(C);
CAP. 2
54
2.7 ConstructorisidestructoriClasesiobiecte
2.7.3 Destructori4. Parametrii transmisi unei functii pot fi obiecte, pointeri
catre obiecte sau referinte catre obiecte. Valoarea returnata de o functie poate fi
un obiect, pointer catre obiect sau referinta catre obiect.
CAP. 2
55
2.7 ConstructorisidestructoriClasesiobiecte
2.7.3 Destructori�ncazulconstructoruluiclaseisegment, acestaestedefinitastfel:
segment::segment(punct&A1,punct &B1) { A=A1;B=B1;cout<<"Constructor segment\n";}
Constructorul primeste ca parametri referinte catre obiecte de tipul punct. Apelul
constructorului: segment S(P, Q); Parametrii efectivi P si Q sunt referinte pentru
A1 si B1 (aceleasi obiecte). Ca urmare, se apeleaza cei doi constructori impliciti
pentru membrii A si B ai segmentului S. �n urma operatiei de atribuire din corpul
constructorului segmentului, ei sunt initializati.
CAP. 2
56
2.7 ConstructorisidestructoriClasesiobiecte
2.7.3 DestructoriMesajelecare voraparela declarareaunuiobiectal claseisegment
sunt:"Constructor pctimplicit!!" (pentrumembrulA al segmentuluiS) "Constructor
pctimplicit!!" (pentrumembrulB al segmentuluiS) "Constructor segment"
(pentrusegmentuluiS)
CAP. 2
57
2.7 ConstructorisidestructoriClasesiobiecte
2.7.3 DestructoriConstructorului puteau sa i se transmita parametri prin pointeri:
segment::segment(punct*A1,punct *B1) { A=*A1;B=*B1;cout<<"Constructor segment\n";}
Apelul: segment S(&P, &Q); Parametrii formali A1 si B1 sunt initializati �n
momentul apelului constructorului cu adresele punctelor P, respectiv Q. Situatia
este similara celei anterioare, mesajele obtinute sunt identice celor obtinute �n
cazul transmiterii parametrilor prin referinta.
CAP. 2
58
2.7 ConstructorisidestructoriClasesiobiecte
2.7.3 DestructoriConstructorului puteau sa i se transmita parametri prin valoare:
segment::segment(punctA1,punct B1) { A=A1;B=B1;cout<<"Constructor segment\n";}
Apelul: segment S(P, Q); �n aceasta situatie, la apel, pentru parametrii formali A1
si B1 se rezerva memorie pe stiva: obiectele locale constructorului, A1 si B1, sunt
initializate prin copiere (la transmiterea parametrilor prin valoare, se realizeaza
o copiere a parametrilor efectivi �n parametrii formali).
CAP. 2
59
2.7 ConstructorisidestructoriClasesiobiecte
2.7.3 DestructoriLa terminarea executiei corpului functiei, punctele A1 si B1 sunt
distruse. De aceea, mesajele din aceasta situatie, sunt:"Constructor
copierepunct!!" (pentruA1, local constructorului) "Constructor copierepunct!!"
(pentruB1, local constructorului) "Constructor pct. implicit!!" (pentrumembrulA al
segmentului) "Constructor pct. implicit!!" (pentrumembrulB al segmentului)
"Constructor segment!" (pentrusegmentulS) "Destructor punct!" (pentruB1, la
iesireadinconstructor) "Destructor punct!" (pentruA1, la iesireadinconstructor)
Clasesiobiecte
60
1. Definitiaclaselor, accesla membri2. Instantiereaclaselor3. Membriiuneiclase4.
Pointerulthis5. Domeniulnumelui, vizibilitatesi timp de viata6. Functiiinline7.
Constructorisidestructori8. Tablouride obiecte9. Functiiprietene(friend)CAP. 2
CAP. 2
61
2.8 Tablouride obiecteClasesiobiecte
Obiecteledeacelasitippotfigrupate�ntablouri.Dacauntablouestedeclaratfaraafiinitiali
zat,pentruconstruireaelementelorsaleseapeleazaconstructorulimplicit.Elementeleunuit
abloupotfiinitializatesicuajutorulconstructorilorcuparametri.
CAP. 2
62
2.8 Tablouride obiecteClasesiobiecte
Exemplul1: Fie claselepunctsisegment implementateanterior.
class punct{ //��� }; class segment{ //���};
//implementareametodelorclaselorpunctsisegment main() {punctP(7, -7), Q(-8, 8);
punctPC=P, QC=Q; punctV[3]; //apelulconstructoruluiimplicit pentrufiecaredin cele3
elementeale vectoruluiV
CAP. 2
63
2.8 Tablouride obiecteClasesiobiecte
punctV1[2]={P, Q}; //apelulconstructoruluide copierepentruelementeleV1[0] siV1[1]
punctV2[2]={punct(10,10), punct(100,100)}; //apelul constructorului cu parametri
pentru fiecare din cele 2 elemente, V2[0] si V2[1] segment SV[2]; /* EROARE:
deoareceexistaun constructor cu parametri, nu se genereazaautomat
constructorulimplicit */ segment SV[2]={segment(PC, P), segment(QC, Q)}; segment
SV[2]={segment(punct(5,5), punct(55,55)); segment (punct(10,10),
punct(100,100))}; }
PROGRAMAREACALCULATOARELORSILIMBAJEDE PROGRAMAREII
Clasesiobiecte
64
1. Definitiaclaselor, accesla membri2. Instantiereaclaselor3. Membriiuneiclase4.
Pointerulthis5. Domeniulnumelui, vizibilitatesi timp de viata6. Functiiinline7.
Constructorisidestructori8. Tablouride obiecte9. Functiiprietene(friend)CAP. 2
CAP. 2
65
2.7 FunctiiprieteneClasesiobiecte
Principiulincapsulariidatelorestebine safie respectatin cadrulelaborariiierarhieide
clase. Cu toateacestea, existasituatiiin care estegreusase
respecteacestprincipiu.De aceea, BjarneStroustrupa introdusun concept
menitsarezolvesiacestesituatiiparticulare, pentrua oferisolutiielegantein
vederearezolvariituturorsituatiilorposibile. Acestconcept estecelde friend, care
permitepracticabatericontrolatede la ideeaprotectieidatelorprinincapsulare.
Mecanismulde friendestebine safie folositnumai
in cazulin care nu existaaltasolutie!
CAP. 2
66
2.7 FunctiiprieteneClasesiobiecte
1
Sintaxadeclarariiuneifunctiiprietenein
cadruldeclaratieiuneiclaseesteurmatoarea:friendNumeFunctieMecanismulde
friend(sauprietenie) a aparutdatoritaimposibilitatiicao metodasafie membrua
maimultorclase.Functiileprietenesuntfunctiicare nu suntmetodeale uneiclase, darcare
au totusiaccesla membriiprivatiaiacesteia. Oricefunctiepoatefi prietenaa uneiclase,
indiferentde naturaacesteia.
CAP. 2
67
2.7 FunctiiprieteneClasesiobiecte
Functiileprietene(friend)suntfunctiine-membrealeuneiclase,careau
accesladatelemembreprivatealeclasei.Functiileprietenealeuneiclasetrebuieprecizate�n
definitiaclasei.
�nacestsens,prototipurileunorastfeldefunctiisuntprecedatedecuv�ntulcheiefriend.Spre
deosebiredefunctiilemembre,functiileprietenealeuneiclasenuposedapointerulimplicitth
is.Deaceea,deosebireaesentiala�ntredouafunctiicarerealizeazaaceleasiprelucrari,ofun
ctiemembrasiofunctieprietena,consta�nfaptulcafunctiaprietenaareunparametru�nplusfat
adefunctiamembru.
CAP. 2
68
2.7 FunctiiprieteneClasesiobiecte
Ofunctiepoatefi�nacelasitimpfunctiemembraauneiclasesifunctieprietenaaalteiclase.�ne
xemplulurmator,f1estefunctiemembraaclaseicls1sifunctieprietenaaclaseicls2.Exemplu:
class cls1{ // . . . int f1(int, char); // f1 -metoda a clasei cls1 // . . . };
class cls2{ //. . . friend intcls1::f1(int, char); // f1 -prietenaa
claseicls2 //. . . };
CAP. 2
69
2.7 FunctiiprieteneClasesiobiecte
�n cazul �n care se doreste ca toate functiile membre ale unei clase sa aiba acces
la membrii privati ai altei clase (sa fie functii prietene), prima clasa poate fi
declarata clasa prietena pentru cea de-a doua clasa. �n exemplul urmator, clasa
cls1 este clasa prietena a clasei cls2. Exemplu:
class cls1; class cls2{ //. . . friendcls1;// clasa cls1 este clasa prietena a
clasei cls2 //. . . };Observatie: Relatia de clasa prietena nu este tranzitiva.
Astfel, daca clasa
cls1 este clasa prietena a clasei cls2, iar clasa cls2 este clasa prietena a clasei
cls3, aceasta nu implica faptul ca, cls1 este clasa prietena pentru cls3.
CAP. 2
70
2.7 FunctiiprieteneClasesiobiecte
Iatasiun exemplu:class Point {friend unsigned long Calcul(unsigned X, unsigned
Y);public:friend unsigned long AltaClasa::Calcul(unsigned X, unsigned
Y);... };unsigned long Calcul(unsigned X, unsigned Y){return X * Y / 2;}unsigned
long AltaClasa::Calcul(unsigned X, unsigned Y){ ... }Dupacum se vededin
exemplulde maisus, nu are nicio importantain
cadrulcareisectiuniestedeclaratafunctiaprietena.
CAP. 2
71
2.7 FunctiiprieteneClasesiobiecte
Claseleprietenesuntclasecare au accesla membriiprivatiaiuneiclase.
Sintaxadeclarariiuneiclaseprieteneeste:
friend class NumeClasaPrietena
Iatasiun exemplu:class PrimaClasa{...};class ADouaClasa{...friendclass
PrimaClasa;};
CAP. 2
72
1.Conceptede bazaale programariiorientate
peobiecte2.Clasesiobiecte3.Supraincarcareaoperatorilor4.Creareaierarhiilorde
clase5.Operatiide intrare/ iesirein limbajulC++6.Implementariale modelelorde
date7.Functiisiclasegenerice8.ExceptiisitratareaacestoraCuprinsulCursului
2.7 FunctiiprieteneClasesiobiecte
In exemplulde maisus, clasaPrimaClasaare accesla
membriiprivatiaiclaseiADouaClasa.Important estesaremarcamcarelatiade prietenienu
estetranzitiva.
Dacao clasaA esteprietenaa claseiB, siclasaB esteprietenaa uneiclaseC, aceastanu
inseamnacaA esteprietenaa claseiC. De asemenea, proprietateade prietenienu se
mostenestein claselederivate.
2
73
CAP. 2
SFARSITUL Capitolului2
Clasesiobiecte
Programareacalculatoarelorsilimbajede programareII

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