Sunteți pe pagina 1din 17

Tema 3. Noiunea de clas n C++ 1. Tipuri abstracte de date.

ntr-un program se pot folosi att date de tipuri predefinite ct i date de tipuri definite de utilizator. Cu datele de tipuri predefinite se pot efectua un ir de operaii, care sunt i ele predefinite. Astfel, cu datele int x, y, a, b; se pot efectua operaiile predefinite pentru numere ntregi. Tipul utilizator definete doar modul de reprezentare al datelor, dar nu i operaiile care pot fi efectuate cu aceste date. De aceea prelucrarea datelor de tipuri predefinite este mai simpl dect prelucrarea datelor de tipuri definite de utilizator. Tipul utilizator nu sta ilete nici-o legtur ntre reprezentarea datelor i operaiile asupra acestor date. !"emplu. Considerm tipul structur ce definete numerele comple"e.
struct COMPLEX { double re; double im;

Aici se definete reprezentarea numerelor comple"e ca o perec#e ordonat de numere dou le. $e pot defini %aria ile de acest tip& COMPLEX !, "; Aceast declaraie spune c ! i " sunt compuse fiecare din ' numere dou le. n acest sens ea este c i declaraia int i, #; care spune c i i # sunt ' numere int. Dar pentru i i # putem li er scrie i $ #, i % &, deoarece pentru tipul int sunt predefinite operaiile respecti%e. (entru ! i " nu a%em ns aa operaii. )u putem scrie ! $ " sau ! ' ". Aceste operaii nu sunt definite. Dar ar fi ine s a%em aa operaii pentru a simplifica folosirea acestor %aria ile, s le putem folosi ca
*

pe cele de tip int. (utem scrie !.re, !.im ca i ".re, ".im pentru a accesa componentele datelor ! i ". Dar acest lucru complic utilizarea lor, difer de utilizarea %aria ilelor x, y. $e pot defini funcii pentru efectuarea operaiilor cu aceste date. De e"emplu, pentru adunarea numerelor comple"e, putem defini funcia&
(oid addcom)lex*COMPLEX+ a, COMPLEX+ b, COMPLEX+ c, { c.re - a.re $ b.re; c.im - a.im $ b.im;

Atunci, pentru COMPLEX !, ", r; apelul addcom)lex*!, ", r, %a efectua adunarea r - ! $ ". n acelai mod se pot defini funcii i pentru alte operaii cu numere comple"e. Dar acest lucru nu spune c aceste funcii pot prelucra numai date de tip COMPLEX i c alte operaii nu pot fi definite. (entru a apropia modul de folosire a tipului COMPLEX de cel al unui tip predefinit, %om include n definiia tipului utilizator nu numai reprezentarea datelor dar i funciile de prelucrare a lor. +om enumera n definiia tipului prototipurile funciilor de prelucrare a datelor de acest tip. C,, permite acest lucru&
struct com)lex { -- reprezentarea datelot double re; double im; -- functii de prelucrare (oid add*com)lex a, com)lex b,; (oid sub*com)lex a, com)lex b,; double modul*,; double ar.*,; ;

'

.unciile enumerate n definiia tipului se numesc /unc0ii membru a structurii comple" sau metode. / funcie mem ru poate fi apelat numai pentru date de tipul respecti%, adic de tipul pentru care funcia este mem ru. .unciile definite n interiorul definiiei tipului utilizator automat sunt funcii inline. De aceea, o funcie mem ru simpl poate fi definit n interiorul definiiei tipului, adic se scrie nu prototipul funciei ci ntreaga definiie& antet i corp. De e"emplu, prototipul double modul* ,; poate fi nlocuit cu definiia
double modul*, { return s1rt*re ' re $ im ' im,;

.unciile mai complicate se declar numai n definiia tipului, iar definiia funciei %a urma nafara definiiei tipului. Dar, n acest caz, ea nu mai este automat funcie inline. / funcie mem ru definit nafara definiiei tipului tre uie s ai numele precedat de numele tipului respecti% i operatorul de rezoluie 22. !"emplu&
(oid com)lex22sub*com)lex a, com)lex b, { re - a.re 3 b.re; im - a.im 3 b.im;

Dac dorim ca funcia s fie inline, atunci artm e"plicit acest lucru&
inline (oid com)lex22sub*com)lex a, com)lex b, { re - a.re 3 b.re; im - a.im 3 b.im;

Cunoatem, c accesul la un mem ru dat al tipului utilizator se face prin operaia . sau 45. (entru apelul unui
0

mem ru funcie se folosesc aceeai operatori& !.modul* ,, )45modul*,. De e"emplu, fie com)lex !, '); ) - +!; double r; !.re - 6; !.im - 71; Atunci, r - !.modul*,; %a calcula modulul numrului comple" !. / ser%m, c nu este necesar prezena e"plicit a unui parametru pentru a accesa data curent prelucrat de funcia mem ru modul* ,. (e lng funciile mem ru ale tipului comple", mai pot fi definite i alte funcii care pot s prelucreze date de acest tip. De e"emplu, fie codul&
double dmodul*com)lex '), { return s1rt*)45re ' )45re $ )45im ' )45im,; com)lex ') - +!; r - dmodul*),;

.uncia dmodul* , nu este mem ru al tipului comple", dar i ea poate prelucra date de acest tip. ns, n acest caz este necesar un parametru pentru a transmite funciei data ce tre uie prelucrat, numrul comple" !. Aici, acest parametru este un pointer spre numrul comple" !. n cazul unei funcii mem ru e"ist n mod implicit un astfel de parametru. Acesta este )ointerul t8is. !l se definete astfel& com)lex 'const t8is; sau ti) 'const t8is; n caz general, pentru tipul utilizator cu numele ti). +aloarea acestui pointer, cu numele presta ilit t8is, se definete la fiecare apel al unei funcii mem ru n felul urmtor& dac apelul se face prin operaia ., adic nume./unctie, atunci t8is are %aloarea +nume. Dac apelul are loc prin intermediul unui pointer, adic )45/unctie, atunci t8is are %aloarea pointerului ).
1

(ointerul t8is se aplic implicit. Astfel, e"presia re ' re $ im ' im din funcia mem ru modul* , este interpretat ca *t8is45re, ' *t8is45re, $ *t8is45im, ' *t8is45im,. 2tilizarea implicit a pointerului t8is simplific mult definirea funciilor mem ru. Acest pointer poate fi utilizat i e"plicit. .unciile mem ru pot fi utilizate i la tipul utilizator union n acelai mod ca i pentru tipul struct. Concluzii. 2n tip de date are ' aspecte. 2nul este legat de reprezentarea datelor i reprezint o mulime de date cu aceeai reprezentare, iar altul reprezint operaiile care sunt definite asupra mulimii respecti%e de date. Tipul de date care include n definiia sa aceste ' aspecte se numete ti) abstract de date *T9:,. (entru tipurile predefinite aceste aspecte sunt strns legate ntre ele i utilizatorul le poate utiliza li er. Comple"itatea pro lemelor impune utilizatorul s foloseasc att tipuri predefinite,ct i noi tipuri definite de el nsui. Dar, dup cum am %zut, n C un tip definit de utilizator precizeaz numai reprezentarea datelor i nu definete operaiile asupra acestor date. Datele struct, union conin numai mem ri date. Acest lucru se sc#im parial n C,,. Aici, n definiia unui tip utilizator, se pot include i mem ri funcii care definesc operaii asupra datelor. Aceste metode ale tipului pot fi aplicate numai la date de tipul respecti%. !le simplific parial utilizarea datelor utilizator. (arial, deoarece pot fi definite i alte funcii, care nu sunt metode ale tipului dar au acces la datele lui. Din aceast cauz, compilatorul nu poate face controale stricte pentru a depista utilizarea eronat a
3

datelor. Cu alte cu%inte, datele nu sunt prote4ate. Acest lucru a condus la noiunea de clas. ntr-o clas se face ascunderea datelor la definiia tipului a stract. Toate datele mem ru sau o parte pot fi prote4ate aa, nct la ele s ai acces doar funciile mem ru ale clasei. C#iar i unele metode ale clasei pot fi prote4ate aa ca ele s poat fi apelate numai de funcii mem ru ale clasei. ;. Noiunea de clas. Clasa este un tip a stract de date. )oiunea a aprut din necesitatea de ascundere a datelor n definiia tipului a stract. Datele clasei pot fi prote4ate prin utilizarea modificatorilor de protecie. 5odificatori de protecie sunt )ublic, )ri(ate, )rotected. (entru a aplica un aa modificator la o dat care%a, se scrie numele modificatorului urmat de semnul 2 n faa declaraiei datei respecti%e. De e"emplu& )ri(ate2 int x; sau )rotected2 int y, !; double "; 5odificatorul )ublic spune c data sau metoda respecti% nu este prote4at i poate fi folosit fr restricii n tot programul. 5odificatorul )ri(ate permite utilizarea datei sau funciei respecti%e doar funciilor mem ru ale clasei. 5odificatorul )rotected permite utilizarea datelor doar funciilor mem ru ale clasei i funciilor claselor deri%ate din clasa respecti%. Domeniul de aciune al unui modificator de protecie este din punctul unde a fost scris i pn la sfritul definiiei clasei sau pn la apariia altui modificator. 5odificatorul )ri(ate este implicit. Definiia unei clase este asemntoare definiiei unei structuri. Cu%ntul struct este nlocuit cu class. De e"emplu&
6

class com)lex {

)ri(ate2 double re; double im; )ublic2 (oid add*com)lex a, com)lex b,; (oid sub*com)lex a, com)lex b,; double modul* , { return s1rt*re ' re $ im ' im,; double ar.* ,; ;

/ clas definete un tip a stract de date. (rotecia datelor n clase este la un ni%el mai nalt dect ascunderea datelor n module. Clasa are o parte pri%at i una pu lic. (artea )ri(at< e"prim specificul datelor din clas i asigur im)lementarea lor. Datele i funciile din partea pri%at pot fi accesate numai de funciile mem ru ale clasei. (artea )ublic< asigur legtura clasei cu restul programului, aduc este inter/a0a dintre clas i program. 7nterfaa conine funcii mem ru care sunt pu lice. (artea pu lic poate conine i date mem ru, nu numai funcii. Dar aceste date nu sunt prote4ate, la ele pot a%ea acces i alte funcii din program, nu numai metodele clasei. .olosirea lor nu este recomandat. 3. Definiia claselor. 2n format al definiiei unei clase este
class nume=clasa { -- declaratii mem ri date -- declaratii mem ri functii lista=de=(ariabile;

!ste asemntor cu definiia tipului struct. Aici nume=clasa este numele tipului definit de utilizator, tipului
8

a stract de date, iar n corpul definiiei, marcat de acolade, sunt declarate partea pri%at i partea pu lic a clasei. n corp sunt declarai toi mem rii date i toi mem rii funcii cu modificatorii de protecie necesari. Dup corpul definiiei poate urma o list de %aria ile de tipul nume=clasa. Ca i la structuri, nume=clasa sau lista=de=(ariabile poate lipsi, dar nu concomitent. Dac nume=clasa lipsete, atunci tipul definit se numete anonim. 2lterior, dup ce definiia clasei a fost fcut, se pot defini i alte %aria ile de acest tip& nume=clasa lista=(ariabile; Aa, pentru tipul a stract com)lex, definit mai sus9 putem declara %aria ile& com)lex !, ", '), x>16?; $e pot declara %aria ile simple, pointeri, ta louri etc. +aria ilele ale crui tip se definesc printr-o clas se numesc obiecte. Deci, un o iect este o %aria il de tipul unei clase, de un tip a stract de date. Despre o iecte se mai spune c ele sunt instan0ieri ale clasei respecti%e. Aadar, ! este o instan0< a clasei com)lex. (rocesul de declaraie a %aria ilelor de tipul unei clase se numete instan0iere. (rocedeul de ascundere a datelor i funciilor n clase prin prote4area lor i permiterea accesului la ele numai metodelor clasei se numete inca)sulare. +om considera, n continuare, c tipurile struct i union definesc n C,, tot clase. Deose irea este c la struct i union implicit toi mem rii sunt )ublic, iar la class toi mem rii sunt )ri(ate. :a struct se poate folosi e"plicit modificatorul )ri(ate, iar la union nu poate fi folosit. / clas poate fi definit incomplet, atunci cnd e necesar s ne referim la ea pn la definiia complet& class
;

name; struct name; sau union name; se arat numai numele clasei urmat de caracterul ; Deci, lipsete corpul definiiei clasei respecti%e. Datele mem ru ale clasei se declar n mod o inuit, ca automatice. 2nele date pot fi declarate cu static. Alte clase de memorie nu sunt permise. / dat mem ru nu poate fi de tipul clasei ce se definete. n sc#im ea poate fi un pointer spre tipul class ce se definete sau o referin la tipul respecti%. n cazul unui tip predefinit iniializarea %aria ilelor este simpl& int x, y - 6; x - 16; (entru o iectele unei clase iniializarea este mai dificil. !a poate fi fcut prin funcii mem ru pu lice ale clasei. Astfel, funcia
(oid com)lex22cit* , { cin 55 re 55 im; ,

dup crearea instanei com)lex !; poate fi apelat cu !.cit* , pentru a iniializa o iectul ! prin introducerea %alorilor necesare de la tastatur. .uncia
(oid com)lex22init*double x - 6.6, double y - 6.6, { re - x; im - y;

poate fi apelat cu !.init* 3, 3, pentru iniializarea o iectului ! prin parametrii funciei. (entru a simplifica iniializarea o iectelor, a fost introdus o funcie mem ru special pentru clase, numit constructor. .iecare clas poate a%ea unul sau mai muli constructori care iniializeaz automat o iectele la instanierea lor. :a fel, orice clas poate a%ea o funcie mem ru numit destructor. !a distruge o iectele clasei respecti%e. Domeniul de e"isten al numelui unei clase este din punctul definiiei pn la sfritul locului respecti%. De
<

o icei, clasele se definesc nafara oricrui loc, la nceputul fiierului surs. @. Obiecte. 2n o iect este o dat de un tip definit de o clas, este o instan a clasei respecti%e. Declaraia unui o iect este asemntoare declaraiei unei date de un tip predefinit& nume=clasa nume=obiect; De e"emplu, com)lex !; De o icei, clasele au constructor, care se apeleaz automat la orice declaraie de o iect. Datele mem ru ale clasei sunt alocate distinct la fiecare declaraie de o iect, adic ele e"ist n attea e"emplare, cte o iecte au fost declarate. !"cepie fac mem rii date statici. 2n mem ru dat static al unei clase e"ist ntr-un singur e"emplar. !l se aloc o singur dat i este comun pentru toate instanele clasei. Declaraia unui mem ru static n definiia clasei este precedat de cu%ntul static. !l mai tre uie declarat i iniializat i nafar, dup definiiei clasei dar fr cu%ntul static. Accesul la datele mem ru se face prin operaiile A.B i A45B2 !.re, )45im. 2n mem ru static poate fi referit i altfel, indicnd numele clasei urmat de operatorul de rezoluie A22B. .unciile mem ru ale clasei e"ist ntr-un sigur e"emplar, comun pentru toate instanele clasei respecti%e. :egtura dintre funcia mem ru i o iectul pentru care ea se apeleaz se face prin operaiile A.B i A45B. n funciile mem ru se poate folosi e"plicit pointerul t8is, care indic spre o iectul curent, adic spre o iectul pentru care se apeleaz funcia. Accesul la funciile mem ru, care nu sunt statice, se face prin aceleai operaii ca i la datele mem ru& A.B i A45B. .unciile mem ru statice pot fi apelate i
*=

independent de orice o iect, c#iar dac nu a fost creat nici-o instan. n acest caz, funcia este apelat prin construcia
nume=clasa22nume=/unctie=membru=statica

i aici nu mai poate fi folosit pointerul t8is. / metod static nu poate apela mem ri nestatici. &. Domeniul unui nume. /rice nume folosit n program are un domeniu, domeniul de e"isten. Acest domeniu se sta ilete la declaraia numelui. !"ist trei tipuri de domenii& local, /iCier i clas<. 2n nume declarat ntr-un loc de instruciuni, inclusi% n corpul unei funcii, are domeniul local. Domeniul ncepe din punctul declaraiei numelui i continu pn la sfritul locului respecti%. 2n aa nume poate fi utilizat n domeniul lui, inclusi% i n locurile interioare, numai dac el nu a fost redeclarat. Dac ntr-un loc interior numele a fost redeclarat, atunci el nu mai poate fi utilizat direct n acel loc. 2n nume declarat nafara oricrui loc sau clase are domeniul /iCier. Domeniul este din punctul definiiei i pn la sfritul fiierului. )umele poate fi utilizat n tot domeniul su, inclusi% n toate locurile din fiier, dac nu a fost redeclarat. n cazul cnd numele este redeclarat ntrun loc din fiier, atunci el poate fi utilizat numai prin intermediul operatorului de rezoluie B22B. / clas definete un tip a stract de date. )umele acestui tip este n acelai timp i numele clasei. Domeniul acestui nume se sta ilete ca i la oricare alt %aria il. )umele clasei poate a%ea domeniul local, domeniul fiier,
**

poate fi redeclarat. (entru a folosi ntr-un loc numele redeclarat al unei clase, numele respecti% tre uie precedat de construcie class 22 nume=clasa. !"emplu&
class a { D { -- declara numele a D D D ;

int a; -- redeclara numele a a - E; --corect class 22 a x; -- declara o iectul " de clasa a D

)umele unui mem ru al unei clase, care nu este pu lic, are domeniul clas<. Aa nume poate fi folosit numai de metodele clasei respecti%e. 5em rii unei clase pot fi o iecte de alt clas, cu numele de4a definit, dar nu pot fi o iecte de clasa care se definete sau de clasa cu numele nc nedefinit. n acelai timp, un mem ru poate fi pointer sau referin la tipul clasei care se definete. !"emplu&
class a { class b {D a x; -- corect, x este un o iect de clasa a, de4a definita b y; -- gresit, in definitia clasei b nu se pot declara o iecte de -- clasa b b '!; -- corect9 , in definitia clasei b se pot declara pointeri -- spre tipul b b+ "; -- corect9 , in definitia clasei b se pot declara referinte de -- tipul b c t; D ;

*'

-- gresit9 clasa c nu a fost definita ;

F. Domenii de vizibilitate. Domeniul de %izi ilitate al unui nume este acea parte a domeniului su de e"isten, unde el poate fi utilizat, adic poate fi accesat. 2n nume este %izi il n tot domeniul su dac nu este redefinit. )umele redefinit ntr-un loc de%ine in%izi il, temporar, pn la ieirea din locul respecti%. 2n nume cu domeniul fiier care nu este nume de clas, redeclarat ntr-un loc, poate fi fcut %izi il cu operatorul B22B, iar pentru clase cu Gclass22G, respecti% Gstruct22G i Gunion22G. 2n nume cu domeniul local, redefinit ntr-un loc interior, nu este %izi il i nu poate fi accesat direct. !l poate fi accesat indirect, printr-un pointer. !"emplu&
{ int x - 3; int ') - +x; D { double x - @.&; -- x din locul e"tern nu mai poate fi accesat direct, el -- este in%izi il, dar poate fi accesat prin pointerul ) ') - 16; D

E. Durata de via a datelor. Durata de e"isten a datelor este perioada, adic timpul, ct datele sunt alocate n memorie. Durata de %ia depinde de clasa de memorie a datelor. !"ist trei tipuri de durat de %ia& durata static<, durata local< i durata dinamic<. Toate datele glo ale i datele declarate cu static, inclusi% cele cu domeniul local, au durata static<. !le sunt alocate la compilare i e"ist pe toat perioada e"ecuiei programului.
*0

Datele cu domeniul local, care nu sunt statice, au durata de e"isten local<. !le sunt alocate la e"ecuie pe sti% sau n registre la intrarea n loc i sunt dealocate la ieirea din locul respecti%. Datele alocate dinamic, adic de programator n timpul e"ecuiei programului, prin funcii ca malloc* ,, calloc* , sau prin operatorul ne" au durata de e"isten dinamic. !le sunt dealocate e"plicit de programator prin funcia /ree* , sau operatorul delete. H. Alocarea i dealocarea obiectelor. Alocarea o iectelor se face n funcie de durata lor de %ia. / iectele cu durata static i local se aloc automat. / iectele cu durata dinamic se aloc de programator cu operatorul ne". >especti%, dealocarea se face automat pentru o iectele cu durata static i local, iar cele cu durata dinamic se dealoc de programator cu delete. Alocarea o iectelor se mai numete crearea sau construirea lor, iar dealocarea se numete distrugerea o iectelor. Alocarea o iectelor glo ale i celor statice cu domeniul fiier se face nainte de e"ecuia funciei main* ,. !le sunt dealocate la terminarea e"ecuiei programului ca o parte din procedura de ieire din funcia main* ,. / iectele locale sunt alocate n momentul cnd domeniul lor de%ine acti%, adic la instanierea lor i sunt dealocate la ieirea din domeniul lor. :a alocarea datelor de tip predefinit i de tip utilizator se poate face i iniializarea lor. Astfel,
*1

int x - 6; struct )unct { double x; double y; I - { 6.6, 6.6 ;

7niializarea o iectelor este mai dificil din cauza proteciei datelor. n acest scop se folosesc funcii mem ru speciale care efectueaz alocarea i iniializarea o iectelor. $e spune c aceste funcii construiesc o iectul i de aceea ele se numesc /unc0ii constructor. Constructorul se apeleaz automat la fiecare instaniere a unui o iect. Dealocarea unui o iect se face cu o funcie mem ru special care se numete destructor. Destructorul se apeleaz automat sau e"plicit de programator. Apelul e"plicit se face pentru a distruge o iectele dinamice. (entru o iecte glo ale destructorul se apeleaz automat la ieirea din main* , prin funcia exit* ,, iar pentru cele cu durata local el se apeleaz automat la ieirea din domeniul o iectului. J. Iniializarea obiectelor. Datele pot fi iniializate la declaraia sau definiia lor. n general, datele de durat static neiniializate e"plicit sunt iniializate automat cu zero la alocarea lor. Datele de alt domeniu, neiniializate e"plicit, au %aloarea iniial impre%izi il. Datele de tip predefinit sau de tip utilizator sunt iniializate ca i n C. n C,,, spre deose ire de C, se poate iniializa prima component a datelor de tip union. Datele de tip ta lou, struct, union i enum pot fi iniializate cu e"presii constante, adic %alorile crora pot fi e%aluate la compilare. (entru alte tipuri de date, se pot folosi la iniializare i e"presii ce nu sunt constante, dar a cror %aloare poate fi e%aluat n momentul iniializrii. !"emplu&
*3

int /* /loat x, /loat y, { /loat ! - 1 $ x $ y; -- corect9 %alorile x, y sunt cunoscute la momentul -- initializarii double r - si!eo/*int, ' K; -- gresit9 %aloarea lui K nu este cunoscuta K - @;

7niializarea o iectelor este mai dificil. !a se face cu a4utorul constructorilor, care sunt apelai automat la instanierea o iectelor. Datele mem ru ale o iectelor statice sunt iniializate automat cu = la crearea o iectelor. (entru alte o iecte, adic cele cu durata local sau dinamic, datele mem ru nu sunt iniializate automat i rmn cu %aloarea iniial nedefinit. Datele mem ru statice ale clasei nu se iniializeaz de constructori, deoarece ele e"ist ntr-un singur e"emplar comun pentru toate o iectele clasei respecti%e. Aceti mem ri statici pot fi iniializai e"plicit, dar nafar, dup definiia clasei. !i sunt declarai i iniializai ca i oricare alt %aria il glo al, dar nu se mai specific cu%ntul static in faa declaraiei. Att doar, c numele %aria ilei este precedat de numele clasei respecti%e i operatorul B22B. !"emplu&
class a { int a22" - 6; int a22u - 1; D int x, y, !; static int ", u; D ;

*6

)u este o ligatoriu ca un mem ru static s fie iniializat e"plicit. n aa caz el este iniializat automat cu = n momentul alocrii. 5enionm, c n acest e"emplu atri uiri de forma a22" - ; sunt permise numai n funciile mem ru ale clasei, deoarece datele ", u sunt pri%ate.

*8