Sunteți pe pagina 1din 13

1. Clase.

Abstractizarea datelor
Vom face n cursul de Programarea calculatoarelor i limbaje de programare II
o introducere n programarea orientat pe obiecte, cu aplicaii n limbajul de
programare C++. Cursul de Programarea calculatoarelor i limbaje de programare I a
realizat o prezentare a elementelor de programare structurat pe care le vom folosi
acum pentru a crea aplicaii care folosesc obiecte. Am introdus, totui, i cteva
concepte de programare obiectual.
Am vzut c programarea orientat pe obiecte (object oriented programming
OOP) ncapsuleaz date (atribute) i funcii (comportamente) n pachete numite
clase. O clas poate fi asemnat cu un proiect, un ablon, o descriere. Avnd la
dispoziie o clas, un programator poate s creeze obiecte din acea clas. Clasele
au proprietatea de ascundere a informaiei (information hiding). Aceasta nseamn
c, dei obiectele pot s comunice unele cu altele prin intermediul unor interfee,
claselor nu le este permis s acceseze detaliile de implementare ale altor clase. Se
spune c detaliile de implementare sunt ascunse n interiorul claselor. Vom vedea de
ce este att de important ascunderea informaiei n ingineria software.
n programarea procedural aplicaiile tind s fie orientate pe aciuni, n timp ce
n programarea obiectual ele sunt, n mod ideal, orientate pe obiecte. n limbajul de
programare C care este unul procedural, unitatea de program este funcia. n C++, n
schimb, unitatea de program este clasa din care pot fi instaniate sau create obiecte.
Programatorii de aplicaii scrise n limbajul C se concentreaz pe scrierea de
funcii. Grupurile de aciuni care realizeaz o operaie formeaz o funcie, iar funciile
sunt grupate pentru a forma un program. Datele sunt importante pentru o aplicaie C,
dar ele sunt privite ca un suport pentru aciunile pe care le realizeaz funciile.
Verbele din setul de specificaii ale unei aplicaii ajut programatorul C s determine
care sunt funciile necesare implementrii sistemului.
Programatorii C++ se concentreaz pe crearea propriilor tipuri de date (userdefined types) numite clase. Clasele se mai numesc si tipuri de dat definite de
programator (programmer-defined types). Fiecare clas conine datele i setul de
funcii care le manipuleaz. Datele care intr n componena unei clase se numesc
date membre. Funciile care intr n alctuirea unei clase se numesc funcii membre.
n alte limbaje de programare, datele membre se numesc proprieti, iar funciile
menbre se numesc metode. O instan a unui tip de dat predefinit (built-in type), de
exemplu int, se numete variabil, n timp ce o instan a unui tip de dat definit de
utilizator, adic a unei clase, se numete obiect. Putem folosi termenul de obiect
poate fi folosit i pentru a ne referi la variabile. n proiectarea unei aplicaii orientate
pe obiecte ne focalizm atenia n principal asupra claselor i mai puin asupra
funciilor. Substantivele din specificaiile unui sistem software ne ajut s identificm
setul de clase care urmeaz a fi folosite pentru crearea obiectelor care, lucrnd
mpreun, implementeaz aplicaia.
Clasele n C++ pot fi privite ca o evoluie de la noiunea de structur din
limbajul C. Vom implementa mai nti un tip de dat folosind o structur. Vom trece
apoi la implementarea aceluiai tip de dat folosind o clas.

1.1Definirea unei structuri


Structurile sunt tipuri de dat agregate definite pe baza altor tipuri de dat
predefinite sau definite de programator.

Programarea calculatoarelor i limbaje de programare II

Exemplu
struct Time
{
int hour;
int minute;
int second;
};
Cuvntul rezervat struct se folosete pentru a defini o nou structur.
Identificatorul Time este numele ales de noi n exemplu pentru a denumi noul tip de
dat definit prin aceast structur. ntre acolade se gsesc membrii structurii.
Membrii aceleiai structuri trebuie s aib nume unice, ns dou structuri diferite pot
conine membri cu aceleai nume. Definiia unei structuri se ncheie cu ;.
O structur nu poate conine un membru al crui tip s fie chiar cel definit de
ea. n exemplul anterior, structura Time nu poate conine un membru de tip Time.
Poate, ns, s conin un membru care este pointer la tipul Time, fiind vorba, n
acest caz, de o structur autorefernial. Aceste structuri sunt utile, e exemplu, atunci
cnd se definesc structuri de date precum listele nlnuite, stivele sau arborii.
Aceast observaie este valabil i pentru clase.
Definiia unei structuri nu implic rezervarea de spaiu de memorie. n schimb,
declaraiile de obiecte dintr-un tip definit printr-o structur presupun alocari de
memorie. Declaraia
Time timeObject, timeArray[10],
*timePtr, &timeRef = timeObject;
declar timeObject ca un obiect de tip Time, timeArray ca tablou de 10
elemente de tip Time, timePtr ca pointer la un obiect de tip Time i timeRef ca
referin la un obiect de tip Time iniializat cu timeObject.

- Accesarea membrilor unei structuri


Membrii unei structuri sau ai unei clase pot fi accesai folosind operatorii de
acces al membrilor. Acetia sunt operatorul . i operatorul ->.
Operatorul . se folosete pentru a accesa membri ai structurilor sau ai claselor
prin intermediul numelui obiectului sau al unei referine la obiect.
Exemplu
cout << timeObject.hour;
cout << timeRef.hour;
n exemplul de mai sus, timeObject este un obiect de tip Time, iar timeRef este
o referin la un obiect de tip Time.
Operatorul -> se folosete pentru a accesa membrii unei structuri sau ai unei
clase prin intermediul unui pointer la un obiect.
Exemplu
timePtr = &timeObject;
cout << timePtr->hour;
n acest exemplu, timePtr este un pointer la un obiect de tip Time i este iniializat
cu adresa de memorie a lui timeObject.

- Implementarea tipului de dat Time folosind o structur


Programul de mai jos tiprete n dou moduri ora stocat ntr-un obiect de tip
Time. Funcia printShort implementeaz tiprirea n formatul de 24 de ore fr s
includ i secundele, iar funcia printLong pe cea n formatul AM/PM.
2

Programarea calculatoarelor i limbaje de programare II

Exemplu
#include <iostream>
using std::cout;
using std::endl;
struct Time //definitia structurii
{
int hour;
//0-23
int minute; //0-59
int second; //0-59
};
void printShort(const Time&);
void printLong (const Time&);
int main()
{
Time dinnerTime; //obiect de tip Time
//asignarea unor valori valide membrilor obiectului
dinnerTime.hour = 18;
dinnerTime.minute = 30;
dinnerTime.second = 0;
cout << "Cina va avea loc la ora ";
printShort(dinnerTime);
cout << " (format scurt), \nadica la ora ";
printLong(dinnerTime);
cout << " (format lung).\n" << endl;
//asignarea unor valori invalide membrilor obiectului
dinnerTime.hour = 29;
dinnerTime.minute = 73;
cout << "Obiect de tip Time cu valori invalide: ";
printShort(dinnerTime);
cout << endl;
return 0;
}
void printShort(const Time &t)
{
cout << (t.hour < 10 ? "0" : "") << t.hour << ":"
<< (t.minute < 10 ? "0" : "") << t.minute;
}
void printLong(const Time &t)
{
cout << ((t.hour == 0 || t.hour == 12) ?
12 : t.hour % 12)
<< ":" << (t.minute < 10 ? "0" : "") << t.minute
3

Programarea calculatoarelor i limbaje de programare II

<< ":" << (t.second < 10 ? "0" : "") << t.second


<< (t.hour < 12 ? " AM" : " PM");
}
Rulnd programul, vom obine urmtorul rezultat:
Cina va avea loc la ora 18:30 (format scurt),
adica la ora 6:30:00 PM (format lung).
Obiect de tip Time cu valori invalide: 29:73
Cele dou funcii de tiprire au parametri de tip referin la un obiect constant
de tip Time. Din acest motiv, ele vor primi referine la obiect, evitndu-se astfel
dezavantajele legate de ocuparea memoriei i a timpului necesar copierii ntregului
obiect. Parametrii fiind de tip const, funciile nu vor putea schimba coninutul
obiectului.
Exist mai multe dezavantaje legate de crearea unor noi tipuri de dat cu
ajutorul structurilor. Iniializarea membrilor nu este cerut n mod explicit, astfel c
am putea avea probleme din cauza folosirii unor date neiniializate. Chiar dac
membrii sunt iniializai, valorile lor pot s nu fie corecte, aa cum am vzut n
exemplu anterior. Lucrul acesta este posibil deoarece programatorul manipuleaz
direct datele membre ale obiectului n lipsa unei interfee care s asigure validarea
valorilor.
O alt problem legat de implementarea tipurilor de dat cu ajutorul structurilor
este c acestea nu pot fi tiprite ca o entitate prin aplicarea operatorului << asupra
unui obiect. Clasele permit aceast facilitate prin suprancrcarea operatorului <<, n
felul acesta operatorul de inserare n stream-ul de scriere cptnd o nou
funcionalitate. n plus, obiectele de tip structur nu pot fi comparate prin operatori
relaionali, n timp ce pentru obiecte de tip clas aceti operatori pot fi suprancrcai.

- Implementarea tipului abstract de dat Time folosind o


clas
Vom reimplementa structura Time printr-o clas C++ i vom prezenta unele
dintre avantajele crerii tipurilor abstracte de date (abstract data types) ca i clase.
Un tip abstract de dat reprezint un set de date i un set de operaii care se aplic
asupra datelor. Clasele i structurile pot fi folosite aproape identic in C++, diferena
dintre cele dou fiind legat de modul implicit de acces la membri.
Clasele permit programatorilor s modeleze obiecte care au atribute,
reprezentate ca date membre i comportamente sau operaii, reprezentate ca funcii
membre. Pentru definirea unei clase folosim n C++ cuvntul cheie class.
n alte limbaje de programare, funciile membre se numesc i metode i sunt
invocate ca rspuns la mesaje trimise ctre un obiect. Un mesaj corespunde unui
apel al unei funcii membre trimis dintr-un obiect altui obiect sau trimis dintr-o funcie
unui obiect.
Odat definit o clas, numele su poate fi folosit n declararea obiectelor
acelei clase.
Exemplu
class Time
{
public:
Time();
void setTime(int, int, int);
void printShort();
4

Programarea calculatoarelor i limbaje de programare II

void printLong ();


private:
int hour;
int minute;
int second;
};
Definiia unei clase ncepe cu cuvntul cheie class. Corpul definiiei clasei este
delimitat de o pereche de acolade { i }. Definiia clasei se termin prin semnul ;.
Clasa Time conine trei date membre de tip ntreg, hour, minute i second, ca i
structura Time descris mai devreme.

Specificatorii de acces la membri : public, protected i private


Etichetele public: i private: se numesc specificatori de acces la membri.
Orice dat membr sau funcie membr declarat dup specificatorul de acces
public i naintea urmtorului specificator de acces la membri este accesibil
oriunde n program unde poate fi utilizat un obiect din clasa Time. Orice dat
membr sau funcie membr declarat dup specificatorul de acces private i
naintea urmtorului specificator de acces la membri este accesibil doar funciilor
membre ale clasei. Specificatorii de acces la membri sunt urmai ntotdeauna de
semnul : i pot aprea de mai multe ori n definiia unei clase. n capitolele
urmtoare, atunci cnd vom prezenta noiunea de motenire vom introduce un al
treilea specificator de acces, protected.
Pentru claritatea programului, se prefer specificarea o singur dat a fiecrui
specificator de acces la membri n definiia unei clase. n general, membrii publici se
plaseaz primii.

Funciile membre
Definiia clasei Time din exemplul de mai sus conine prototipurile celor patru
funcii membre. Acestea sunt aezate dup specificatorul public (n seciunea
public a clasei) i se numesc Time, setTime, printShort i printLong.
Acestea se numesc funcii membre publice sau servicii publice sau comportamente
publice sau interfaa clasei. Aceste funcii pot fi folosite de clienii clasei pentru a
manipula datele clasei. Clienii clasei sunt poriunile de program care folosesc
obiecte ale clasei. Datele membre ale clasei reprezint suportul pentru serviciile
oferite de clas clienilor si prin intermediul funciilor membre. Serviciile permit
codului client s interacioneze cu un obiect al casei.
n lista de funcii membre se gsete una care are acelai nume cu cel al clasei.
Ea este o funcie special care se numete constructor al clasei i care are rolul de a
iniializa membrii unui obiect al clasei. Constructorul clasei este apelat automat atunci
cnd se creeaz n memoria calculatorului un obiect al clasei. O clas poate avea
mai muli constructori, acest lucru fiind posibil prin mecanismul suprancrcrii
funciilor. Pentru funciile constructor nu se specific niciun tip al valorii returnate,
deci ele nu ntorc valori.

Datele membre
n definiia clase Time, cele trei date membre, hour, minute i second, apar
dup specificatorul de acces private. Acesta indic faptul c cei trei membri sunt
accesibili doar funciilor membre sau, aa cum vom vedea ntr-unul dintre capitolele
urmtoare, prietenilor clasei. Datele membre poti fi accesate doar de cele patru
5

Programarea calculatoarelor i limbaje de programare II

funcii membre care apar n definiia clasei. Se obinuiete ca datele membre s fie
listate n seciunea private a unei clase i funciile membre n seciunea public a
clasei. Vom vedea c putem avea i funcii private i date membre publice. Cu toate
acestea, este considerat o greeal de proiectare a unei aplicaii orientate pe
obiecte folosirea datelor membre publice.

Obiectele
Un obiect const dintr-o copie a setului de date membre declarate n clas.
Funciile membre sunt partajate ntre toate obiectele unei clase, neexistnd copii ale
funciilor pentru fiecare obiect n parte.
Odat definit o clas, aceasta poate fi folosit ca tip de dat pentru declararea
obiectelor, tablourilor, pointerilor sau referinelor. Tipul de dat introdus printr-o clas
poate fi utilizat n acelai fel ca i tipurile predefinite. Putem avea ntr-un program mai
multe obiecte dintr-o clas, aa cum putem avea mai multe variabile de tip int.
Programatorul poate s creeze oricte tipuri de dat are nevoie ntr-un program. Din
acest motiv, limbajul C++ se spune c este un limbaj extensibil.
Exemplu
Time sunset,
//obiect de tip Time
arrayOfTimes[5],
//tablou de obiecte Time
*pointerToTime,
//pointer la un obiect de tip Time
&dinnerTime = sunset; //referinta la un obiect Time
n programul urmtor vom folosi clasa Time pentru a nlocui tipul de dat definit
prin structura Time. Vom vedea cum se definesc funciile membre, cum se declar
(instaniaz) obiecte ale clasei Time i cum se apeleaz funciile membre.
Exemplu
#include <iostream>
using std::cout;
using std::endl;
//Declaratia tipului abstract de
class Time
{
public:
Time();
void setTime(int, int, int);
void printShort();
void printLong ();
private:
int hour;
//0-23
int minute; //0-59
int second; //0-59
};

data Time

//constructor
//asignarea valorilor
//tiparire in format scurt
//tiparire in format lung

//Constructorul clasei Time initializeaza


//toate datele membre cu valoarea 0.
//Ne asiguram astfel ca orice obiect de tip
//Time porneste dintr-o stare consistenta.
Time::Time()
{

Programarea calculatoarelor i limbaje de programare II

hour = minute = second = 0;


}
//Asignarea unor noi valori datelor membre din Time
//Este verificata validitatea datelor
//Valorile invalide sunt inlocuite cu 0
void Time::setTime(int h, int m, int s)
{
hour = (h >= 0 && h < 24) ? h : 0;
minute = (m >= 0 && m < 60) ? m : 0;
second = (s >= 0 && s < 60) ? s : 0;
}
void Time::printShort()
{
cout << (hour < 10 ? "0" : "") << hour << ":"
<< (minute < 10 ? "0" : "") << minute;
}
void Time::printLong()
{
cout << ((hour == 0 || hour == 12) ?
12 : hour % 12)
<< ":" << (minute < 10 ? "0" : "") << minute
<< ":" << (second < 10 ? "0" : "") << second
<< (hour < 12 ? " AM" : " PM");
}
int main()
{
Time t; //instantiaza obiectul t de tip Time
cout << "Valoarea initialia in format scurt este ";
t.printShort();
cout << "\nValoarea initialia in format lung este ";
t.printLong();
t.setTime(13, 27, 6);
cout << "\n\nOra in format scurt dupa setTime este ";
t.printShort();
cout << "\nOra in format lung dupa setTime este ";
t.printLong();
//asignarea unor valori invalide membrilor obiectului
t.setTime(99, 99, 99);
cout << "\n\nDupa asignarea valorilor invalide:"
<< "\nOra in format scurt: ";
t.printShort();
cout << "\nOra in format lung: ";
t.printLong();
cout << endl;
7

Programarea calculatoarelor i limbaje de programare II

return 0;
}
Rulnd programul, vom obine urmtorul rezultat:
Valoarea initialia in format scurt este 00:00
Valoarea initialia in format lung este 12:00:00 AM
Ora in format scurt dupa setTime este 13:27
Ora in format lung dupa setTime este 1:27:06 PM
Dupa asignarea valorilor invalide:
Ora in format scurt: 00:00
Ora in format lung: 12:00:00 AM
Programul instaniaz obiectul t de tip Time. Atunci cnd este instaniat acest
obiect, constructorul clasei Time este apelat automat. Conform definiiei acestei
funcii, datele membre private hour, minute i second sunt iniializate cu valoarea
0. Funcia membr setTime asigneaz valori noi celor trei date membre, iar funciile
printShort i printLong tipresc ora n format scurt i n format lung.
Datele membre ale clasei Time sunt private, nefiind accesibile din afara clasei.
Conform principiilor programrii orientate pe obiecte, reprezentarea datelor din
interiorul clasei este n afara zonei de interes a clientului clasei. De exemplu, o alt
reprezentare a orei ar putea fi sub forma numrului de secunde scurs de la miezul
nopii. Clienii ar putea folosi aceleai funcii membre publice, obinnd aceleai
rezultate fr s cunoasc aceste detalii. Astfel, implementarea unei clase se spune
c este ascuns clienilor. Ascunderea informaiei reprezint imposibilitatea de a
accesa detaliile de implementare ale unei clase prin metode din afara sa.
Ascunderea informaiei promoveaz posibilitatea de a modifica programele i de a
simplifica percepia clienilor asupra unei clase. Dac implementarea unei clase se
schimb, de exemplu pentru a i mbunti performanele, interfaa clasei rmnnd
neschimbat, programul client nu trebuie modificat. Acest avantaj face ca
modificarea unui sistem s fie mult mai uoar.
n programul de mai sus, constructorul clasei Time iniializeaz datele membre
cu valori 0. Acest lucru asigur faptul c obiectele sunt ntr-o stare consistent atunci
cnd sunt create. Obiectele de tip Time nu pot conine valori iniiate aleatoare
invalide deoarece constructorul este apelat automat, conform mecanismelor
implementate de orice limbaj de programare orientat pe obiecte. Nici operaiile
ulterioare nu pot introduce valori incorecte n datele membre ale obiectelor Time
pentru c funcia setTime a fost scris n aa fel nct verific ncadrarea n
domeniile dorite a ntregilor care se vor stoca.
Diagrama UML a clasei Time este urmtoarea:
Time
-hour : int = 0
-minute : int = 0
-second : int = 0
+setTime(h : int, m : int, s : int):
+printShort() : void
+printLong() : void
8

void

Programarea calculatoarelor i limbaje de programare II

Membrii private sunt marcai prin semnul -, iar cei public prin +. Valorile
iniiale are datelor membre sunt specificate n dreptul fiecreia dintre ele dup
semnul =. Datele membre nu pot fi iniializate atunci cnd sunt declarate n corpul
claselor. O astfel de operaie produce o eroare de compilare. Datele membre trebuie
iniializate de constructorii claselor sau li se pot asigna valori prin funcii de tip set.
O funcie care are acelai nume cu cel al clasei dar este precedat de
caracterul tilda (~) se numete destructor al clasei. Cu ajutorul lor, programatorul
poate implementa operaiile care consider c trebuie realizate nainte de eliberarea
memoriei care a fost alocat obiectului. Destructorii sunt funcii care nu pot avea
argumente, deci nu pot fi suprancrcai.
Adeseori, clasele nu trebuie create de la zero, ci pot fi derivate din alte clase
care ofer atribute i comportamente care pot fi refolosite. O alt posibilitate este
posibilitatea de a include n noile clase obiecte altor clase ca membri. Reutilizarea
codului n aceast manier poate crete semnificativ productivitatea n dezvoltarea
software. Derivarea noilor clase din clase existente se numete motenire, iar
includerea obiectelor unei clase ca membri n alte clase se numete compunere sau
agregare.

- Domeniul clas i accesarea membrilor unei clase


Datele i funciile membre ale unei clase aparin aceluiai domeniu, numit
domeniu clas.
Funciile membre pot fi definite n interiorul definiiei clasei, dar se prefer
definirea funciilor n afara definiiei clasei. Atunci cnd funciile membre sunt definite
n afara clasei, numele trebuie precedat de numele clasei i de operatorul domeniu
::. Acest lucru este necesar pentru c diversele clase definite n program pot
conine funcii membre cu aceleai nume. Distincia este fcut de clasele crora le
aparin aceste funcii.
Chiar dac o funcie membr este declarat n afara clasei, ea face parte tot din
domeniul clasei, adic ea poate fi accesat doar de celelalte funcii membre ale
clasei sau prin intermediul unui obiect al clasei, o referin la un obiect al clasei sau
un pointer la un obiect al clasei.
Funciile membre au acces direct la ceilali membri, fr a fi nevoie s i apeleze
prin intermediul unor obiecte. Acest lucru poate fi observat comparnd modul n care
sunt scrise funciile printShort i printLong din clasa Time, care nu au
argumente, i funciile printShort i printLong din structura Time prezentat n
seciunea precedent. Programarea orientat pe obiecte simplific adeseori apelurile
de funcii prin reducerea numrului de parametri care trebuie transmii. Acest
beneficiu deriv din faptul c ncapsularea datelor i a funciilor ntr-un obiect d
dreptul funciilor membre s acceseze n mod direct datele membre.
n interiorul domeniului clas, toi membrii pot fi accesai de toate funciile
membre i pot fi referii prin nume. n afara domeniului clasei, membrii sunt referii
printr-un obiect, o referin la un obiect sau un pointer la un obiect.
Funciile membre ale unei clase pot fi suprancrcate doar de funcii membre
din aceeai clas.
Variabilele definite ntr-o funcie membr fac parte din domeniul funciei, fiind
cunoscute doar acelei funcii. Dac o funcie membr definete o variabil cu acelai
nume ca una din domeniul clasei, cea din urm este ascuns de prima. ntr-o astfel
de situaie, variabila din domeniul clasei poate fi folosit doar dac numele este
precedat de operatorul domeniu ::.

Programarea calculatoarelor i limbaje de programare II

Operatorii folosii pentru a accesa membrii unei clase sunt identici cu cei folosii
pentru accesul membrilor unei structuri. Operatorul punct . se folosete n
combinaie cu numele unui obiect sau cu cel al unei referine la un obiect pentru a
accesa membrii obiectului. Operatorul sgeat -> se folosete n combinaie cu un
pointer la un obiect pentru a accesa membrii obiectului.

- Separarea interfeei de implementare


Unul dintre principiile fundamentale ale ingineriei software este separarea
interfeei unei clase de implementarea sa. Aceasta face ca programul s poat fi
modificat mult mai uor. De regul, declaraia unei clase se plaseaz ntr-un fiier
header care va fi inclus de codul client n care urmeaz s fie folosit clasa. n felul
acesta, furnizorii de software pot oferi biblioteci de clase pentru vnzare sau
liceniere prin publicarea fiierelor header, implementrile fiind sub forma modulelor
obiect. Detaliile de implementare rmn astfel protejate, spre deosebire de varianta
n care definiia clasei i implementarea sa se afl n acelai fiier.
Cu toate acestea, fiirele header pot conine segmente de cod care
implementeaz unele aciuni sau legturi ctre astfel de segmente de cod. Funciile
membre de tip inline sunt funcii, de preferat de dimensiuni reduse, definite n
interiorul clasei, odat cu definiia funciei. Particular funciilor inline este c, la
compilare, apelul lor este nlocuit cu corpul funciei. O funcie definit n afara
definiiei clasei poate deveni inline prin includerea cuvntului cheie inline n
headerul su. Pe de alt parte, membrii privai sunt listai n fiierul header care
conine definiia clasei, ei fiind vizibili utilizatorilor clasei chiar dac nu le sunt
accesibili.
Aplicnd principiul separrii interfeei de implementare, programul care
implementeaz i testeaz clasa Time pe care l-am scris mai devreme va fi separat
n trei fiiere: time.h care conine definiia clasei Time, time.cpp care conine
implementarea funciilor membre ale clasei i test_time.cpp care testeaz clasa.
Atunci cnd scriem un program C++, fiecare definiie a unei clase se plaseaz ntr-un
fiier header i definiiile funciilor membre ale clasei ntr-un fiier surs care are
acelai nume de baz cu numele fiierului header.
Exemplu
time.h
//Previne includerile multiple ale fisierului header
#ifndef TIME_H
#define TIME_H
//Declaratia tipului abstract de data Time
class Time
{
public:
Time();
//constructor
void setTime(int, int, int); //asignarea valorilor
void printShort();
//tiparire in format scurt
void printLong ();
//tiparire in format lung
private:
int hour;
//0-23
int minute;
//0-59
int second;
//0-59
};
#endif
10

Programarea calculatoarelor i limbaje de programare II

time.cpp
#include <iostream>
using std::cout;
#include "time.h"
//Constructorul clasei Time initializeaza
//toate datele membre cu valoarea 0.
//Ne asiguram astfel ca orice obiect de tip
//Time porneste dintr-o stare consistenta.
Time::Time()
{
hour = minute = second = 0;
}
//Asignarea unor noi valori datelor membre din Time
//Este verificata validitatea datelor
//Valorile invalide sunt inlocuite cu 0
void Time::setTime(int h, int m, int s)
{
hour = (h >= 0 && h < 24) ? h : 0;
minute = (m >= 0 && m < 60) ? m : 0;
second = (s >= 0 && s < 60) ? s : 0;
}
void Time::printShort()
{
cout << (hour < 10 ? "0" : "") << hour << ":"
<< (minute < 10 ? "0" : "") << minute;
}
void Time::printLong()
{
cout << ((hour == 0 ||
12 : hour % 12)
<< ":" << (minute
<< ":" << (second
<< (hour < 12 ? "
}
test_time.cpp
#include <iostream>
using std::cout;
using std::endl;

hour == 12) ?
< 10 ? "0" : "") << minute
< 10 ? "0" : "") << second
AM" : " PM");

#include "time.h"
int main()
{
Time t; //instantiaza obiectul t de tip Time
cout << "Valoarea initialia in format scurt este ";
11

Programarea calculatoarelor i limbaje de programare II

t.printShort();
cout << "\nValoarea initialia in format lung este ";
t.printLong();
t.setTime(13, 27, 6);
cout << "\n\nOra in format scurt dupa setTime este ";
t.printShort();
cout << "\nOra in format lung dupa setTime este ";
t.printLong();
//asignarea unor valori invalide membrilor obiectului
t.setTime(99, 99, 99);
cout << "\n\nDupa asignarea valorilor invalide:"
<< "\nOra in format scurt: ";
t.printShort();
cout << "\nOra in format lung: ";
t.printLong();
cout << endl;
return 0;
}
Definiia clasei este inserat n interiorul urmtorului cod destinat
preprocesorului:
//Previne includerile multiple ale fisierului header
#ifndef TIME_H
#define TIME_H
...
#endif
n programele de dimensiuni mari, cu multe fiiere header care la rndul lor includ
alte fiiere header, pot aprea situaii n care unul dintre ele ar putea fi inclus de mai
multe ori. Aceste directive de preprocesare se folosesc pentru a preveni includerea
multipl care conduce la erori de compilare.

- Controlul accesului la membri


Specificatorii de acces la membrii unei clase, public, private i protected
se folosesc pentru a controla accesul la datele membre i la funciile membre.
Specificatorul implicit de acces a membrii unei clase este private, astfel c
membrii care se gsesc imediat dup headerul clasei, n lipsa vreunui specificator
sunt privai. n interiorul unei clase, specificatorii public, private i protected
se pot repeta, ns aceast modalitate de programare nu este uzual pentru c este
o surs de confuzii.
Membrii private ai unei clase pot fi accesai doar de funciile membre sau de
prietenii clasei. Membrii public ai unei clase pot fi accesai de orice funcie din
program.
Scopul membrilor public este de a prezenta clienilor clasei serviciile
(comportamentele) pe care acestea le ofer. Setul de servicii formeaz interfaa
public a clasei. Clienii clasei nu sunt interesai de modul n care sunt implementate
aceste funcii.
n exemplul urmtor demonstrm c membrii private nu pot fi accesai de codul
client, iar compilatorul semnaleaz acest tip de erori.
12

Programarea calculatoarelor i limbaje de programare II

Exemplu
test_private.cpp
#include <iostream>
using std::cout;
#include "time.h"
int main()
{
Time t;
//Eroare: Time::hour nu este accesibil
t.hour = 7;
//Eroare: Time::minute nu este accesibil
cout << "minute=" << t.minute;
return 0;
}
La compilare, apar urmtoarele erori:
C:\Dev-Cpp\Project\PCLPII\C1\Ex4\/time.h:
main()':

In

C:\Dev-Cpp\Project\PCLPII\C1\Ex4\/time.h:13:
Time::hour' is private

function

`int

error:

`int

C:\Dev-Cpp\Project\PCLPII\C1\Ex4\test_private.cpp:11:
within this context
C:\Dev-Cpp\Project\PCLPII\C1\Ex4\/time.h:14:
Time::minute' is private

error:

C:\Dev-Cpp\Project\PCLPII\C1\Ex4\test_private.cpp:14:
within this context

13

error:
`int
error:

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