Sunteți pe pagina 1din 14

Valeriu Iorga

Clase. 1. Programare procedural Programare orientat pe obiecte. 2. Declararea claselor. 3. Operatorul de rezoluie. 4. Funcii membre inline. 5. Referine. 6. Constructori i destructori. 7. Pointerul this. 8. Membri statici ai claselor. 9. Funcii membre constante. 10. Funcii care returneaz referine. 11. Probleme.

Programare n C / C++

1. Programare procedural Programare orientat pe obiecte. Limbajul C, ca i Pascal, utilizeaz modelul programrii structurate procedurale, care const n descompunerea programului n proceduri (funcii), apelate n ordinea n care se desfoar algoritmul. Datele sunt separate de funciile care le manipuleaz. Odat cu creterea dimensiunii programelor s-a acordat o atenie sporit organizrii datelor funciile, mpreun cu datele pe care le manevreaz sunt organizate ca un modul. Programarea modular este tot programare procedural, cu proceduri i date grupate n module i ascunse altor module. Programarea orientat pe obiecte const n identificarea unor obiecte, cu operaii (metode) specifice asociate i realizarea comunicrii ntre aceste obiecte prin intermediul unor mesaje. Elementul constructiv obiectul este o instan a unei clase (tip de dat definit de utilizator). Clasele sunt membre ale unei ierarhii i sunt corelate ntre ele prin relaii de motenire. Un limbaj de programare pune la dispoziia utilizatorilor un numr de tipuri primitive (sau predefinite). Astfel n C avem ca tipuri primitive char, int, float, etc. Un tip de date este precizat printr-o mulime finit de valori T (constantele tipului) i o mulime de operatori (aplicaii T T sau T T T). ntr-un limbaj de programare un tip de date reprezint un model matemaic. Astfel tipul int , caracterizat prin mulimea finit de ntregi (-32768, 32767) i operatorii binari +, -, *, / i % ilustreaz conceptul de numr ntreg. Modelele matemaice care nu au reprezentare direct prin tipuri predefinite se pot reprezenta prin tipuri definite de utilizator (numite i tipuri de date abstracte- TDA). 2. Declararea claselor. O clas reprezint un tip definit de utilizator. Declararea unei clase se face ntr-o manier asemntoare declarrii structurilor i conine att date ct i funcii (metode) i putem declara variabile de acest tip nou. Un obiect este un exemplar sau o instan a unei clase (n vechea terminologie obiectul este echivalent unei variabile, iar clasa este echivalentul unui tip definit de utilizator). Considerm conceptul Data, pe care-l reprezentm printr-o structur i un set separat de funcii de manipulare: struct Data{ int a, l, z; }; void void void void // reprezentare int, int); //initializare //adauga un an //adauga o luna //adauga o zi

initD(const Data&, int, ad_a(const Data&, int); ad_l(const Data&, int); ad_z(const Data&, int);

Valeriu Iorga

Programare n C / C++

Nu exist o legtur implicit ntre date i funciile de manipulare a lor. Pentru a stabili aceast legtur, declarm funciile ca membre ale structurii: struct Data{ int a, l, z; // reprezentare ..// functii de manipulare void initD(int, int, int); // initializare void ad_a(int); void ad_l(int); void ad_z(int); }; Funciile declarate n definirea clasei (structura este o clas) se numesc funcii membre i pot fi apelate numai de variabile de tipul corespunztor (obiecte) folosind sintaxa de acces la membrii structurii: Data d; d.initD(2001, 10, 15); d.ad_a(3); . . . Definirea funciilor membre, n afara clasei se face folosind operatorul de vizibilitate (rezoluie), care indic faptul c funcia aparine clasei specificate naintea acestui operator. void Data::initD(int aa, int ll, int zz){ a = aa; l = ll; z = zz; }; Declararea unei clase se face n mod asemntor cu declararea unei structuri. Cuvntul struct este nlocuit prin class, iar cmpurile se separ n date membre i funcii membre (sau metode). n plus, se pot preciza specificatori de acces la membri. Acetia pot fi: private membrii sunt accesibili numai din interiorul clasei

public membrii sunt accesibili din afara clasei protected membrii sunt accesibili din interiorul clasei i din clasele derivate

Domeniul de definiie al clasei este cuprins ntre nceputul definiiei clasei ( class nume) i sfritul definiiei. Domeniul unui specificator de acces se ntinde din locul unde apare, pn la urmtorul specificator de acces. Dac nu apare nici un specificator de acces, accesul la membrii clasei nu va fi permis din afara ei (implicit se consider specificatorul private). Datele clasei (definind structura sau starea) fiind private sunt ncapsulate, adic ascunse utilizatorului. Acesta nu le poate accesa direct, ci numai prin intermediul unor funcii de acces publice, care aparin interfeei ce definete comportarea clasei. (de obicei datele sunt private i funciile sunt publice.) //declararea clasei (interfata) class Data{ int a, l, z; // reprezentare public: void initD(int, int, int); void ad_a(int); void ad_l(int); void ad_z(int); }; Variabilele ce apar n declaraia clasei (datele membre), fiind private, pot fi folosite numai de ctre funciile membre.

Valeriu Iorga

Programare n C / C++

Funciile membre din partea public pot fi accesate de ctre oricine. O structur este o clas cu toi membrii publici. Un alt exemplu - clasa punct; are ca date membre abscisa i ordonata, iar accesul la ele va fi oprit; ca funcii membre vom prevedea: iniializarea, funcii de acces la date, de setare date i afiarea. #include <iostream.h> #include <iomanip.h> // declaraia clasei class punct{ private: double x0, y0; // date membre public: void init(double x=0, double y=0){ x0 = x; y0 = y; }; void setx(double x){ x0 = x; }; void sety(double y){ y0 = y; }; double getx(){ return x0; }; double gety(){ return y0; }; void afisare(){ long f = ios::fixed; cout << setiosflags(f) << setw(6) << setprecision(2); cout << ( << x0 << , << y0 << ) << endl; }; }; void main(){ punct z1, z2, z; z1.init(1, 2); z2.setx(3); z2.sety(4); z.init(z1.getx(),z2.gety()); z.afisare(); } Se prefer ca definirea funciilor clasei (n afara cazurilor n care acestea sunt foarte mici), s se fac n afara clasei, funciile membre fiind date numai prin semnturile lor. n acest caz putem separa definirea clasei de implementarea ei. Utilizatorului clasei i se asigur ca interfa, numai definirea clasei, fiindu-i ascuns implementarea ei. // definirea clasei fisierul punct.h class punct{ private: double x0, y0; // date membre public: void init(double x=0, double y=0); void setx(double x=0); void sety(double y=0); double getx(); double gety(); void afisare(); }; 3. Operatorul de rezoluie.

Valeriu Iorga

Programare n C / C++

ntruct definirea funciilor se va face n afara domeniului de definiie al clasei, numele funciei trebuie s fie nsoit de numele clasei, i s fie separat de aceasta prin operatorul de rezoluie sau vizibilitate ( :: ). Aadar, implementarea clasei, (fiierul punct.cpp) va fi: // fisierul punct.cpp #include <iostream.h> #include <iomanip.h> void punct::init(double x, double y){ x0 = x; y0 = y; }; void punct::setx(double x){ x0 = void punct::sety(double y){ y0 = double punct::getx(){ return x0; double punct::gety(){ return y0; x; }; y; }; }; };

};

void punct::afisare(){ long f = ios::fixed; cout << setiosflags(f) << setw(6) << setprecision(2); cout << ( << x0 << , << y0 << ) << endl; };

De obicei declararea clasei (interfaa) i definirea ei (implementarea) se fac n fiiere separate. Declaraia unei clase se face ntr-un fiier antet. Un fiier antet trebuie inclus o singur dat n fiierul programului. Pentru a evita includerea multipl de fiiere antet se utilizeaz directive #ifndef sub forma: #ifndef _simbol_ #define _simbol_ declaraie clas (fiier antet) #endif Programul care utilizeaz clasa punct este un program constituit din mai multe fiiere, care vor alctui un proiect. El va conine o directiv de includere a fiierului de interfa punct.h pentru definirea clasei. La prima ntlnire a fiierului antet, simbolul nu este definit, incluzndu-se fiierul antet. Dup prima includere, simbolul fiind definit se ignor poriunea cuprins ntre #define i #endif. Fiierul de implementare conine definiiile metodelor, directiva de includere a fiierului antet al interfeei i alte directive de includere de fiiere. #include <iostream.h> #include clasa.h // definitii funcii membre ale clasei Programul utilizator (al treilea fiier) va conine: includerea diverselor fiiere antet, includerea fiierului antet al clasei i funcia main(). #include <iostream.h> #include clasa.h void main(){ . . . } 4. Funcii membre inline. Funciile mici, cu puine instruciuni, apelate frecvent se compileaz ineficient (se rezerv spaiu n stiv pentru parametrii i rezultat, se efectueaz salt la funcie i apoi salt pentru revenire). Mult mai

Valeriu Iorga

Programare n C / C++

eficient ar fi expandarea apelului funciei prin corpul ei, ca n macroinstruciuni. Apelul unei funcii declarate inline este nlocuit la compilare prin corpul funciei (apel realizat prin expandare). O funcie inline nu trebuie s conin bucle. Funciile membre definite n interiorul clasei sunt n mod implicit inline, dar este posibil ca i funcii definite n afara clasei s fie declarate explicit inline (expandate). class Data{ public: int zi(); . . . private: int a, l, z; }; // functie declarata in mod explicit inline inafara clasei inline int Data::zi(){return z;}; // definirea clasei fisierul punct.h class punct{ private: double x0, y0; // date membre public: inline void init(double x=0, double y=0); //nu era necesara inline void setx(double x=0){ x0=x; }; //declararea explicita inline void sety(double y=0){ y0=y; }; //erau considerate inline double getx(){ return x0; }; // este implicit inline double gety(){ return y0; }; void afisare(); }; // fisierul punct.cpp #include <iostream.h> #include <iomanip.h> //desi inline x0 = y0 = }; este definita in afara clasei este inline (apel expandat) void punct::init(double x, double y){ x; y;

};

//nu este inline (apel=salt cu revenire) void punct::afisare(){ long f = ios::fixed; cout << setiosflags(f) << setw(6) << setprecision(2); cout << ( << x0 << , << y0 << ) << endl; }; 5. Referine.

O referin se comport ca un pointer constant, care este n mod automat derefereniat. Referinele se folosesc: n listele de parametri ale funciilor ca valori de ntoarcere ale funciilor

La creerea unei referine, aceasta trebuie iniializat cu adresa unui obiect (nu cu o valoaren constant). int x;

Valeriu Iorga
int& rx = x; //referinta initializata cu o adresa

Programare n C / C++

Referina poate fi privit ca un pointer inteligent, a crui iniializare este forat de ctre compilator (la definire) i care este derefereniat automat. Spre deosebire de pointeri: referinele sunt iniializate la creere (pointerii se pot iniializa oricnd) referina este legat de un singur obiect i aceast legtur nu poate fi modificat pentru un alt obiect nu exist referine nule ele sunt totdeauna legate de locaii de memorie 6. Constructori i destructori. Iniializarea asigurat de funcia membru init() este lsat la laitudinea utilizatorului. Este de preferat o iniializare mai sigur a obiectului, care s se fac n mod implicit la declararea obiectului. Iniializarea obiectelor se face prin intermediul unor funcii speciale numite constructori. Folosirea funciei initD() pentru iniializarea obiectelor clasei Data este nesigur putem uita s facem iniializarea sau s facem o iniializare repetat. Un obiect poate fi declarat neiniializat sau iniializat. Exemple: Complex z; Complex z1(-1.5, 2.); // obiect neiniializat // obiect initializat

O soluie sigur o reprezin declararea unei funcii avnd scopul explicit de iniializare a obiectelor. O asemenea funcie poart numele de constructor. Constructorul este o funcie public, care iniializeaz datele membre, avnd acelai nume cu numele clasei i care nu ntoarce nici o valoare. class Data{ . . . public: Data(int, int, int); // constructorul . . . }; Considerm definiia clasei Complex: #include <stdio.h> class Complex{ private: double re, im; public: void scrie(); }; void Complex::scrie(){ printf((%4.1lf , %4.1lf)\n, re, im); }; void main(){ Complex z; //obiect neinitializat z.scrie(); } Programul este corect din punct de vedere sintactic. Lipsa unui constructor definit de utilizator, care s iniializeze obiectele este remediat de compilator. Astfel, pentru clasa C, dac nu se definete n mod explicit un constructor, compilatorul genereaz n mod implicit constructorul: C::C(){}, care creaz datele membre ale clasei. Acest constructor implicit nu face nici o iniializare a datelor membre, aa c se vor afia nite valori foarte mari, reprezentnd coninutul memoriei neiniializate.

Valeriu Iorga

Programare n C / C++

Pentru a evita aceasta, se recomand programatorului s i defineasc un constructor implicit (fr parametri), care s iniializeze datele membre (n exemplul nostru iniializarea la 0 pentru partea real i cea imaginar a obiectului numr complex). Constructorul implicit acioneaz asupra obiectelor neiniializate. Clasa Complex, prevzut cu acest constructor este: class Complex{ private: double re, im; public: Complex(){re=0.; im=0.}; void scrie(); }; Se prefer scrierea constructorului, folosind o list de iniializare, conform sintaxei: Complex() : re(0.), im(0.){}; De aceast dat, n urma execuiei se va afia ( 0.0 , 0.0). Dac se declar obiecte iniializate, iniializarea acestora trebuie fcut de ctre un constructor de iniializare, care trebuie definit n mod explicit de ctre utilizator. Pentru clasa Complex, un constructor de iniializare, are forma: class Complex{ private: double re, im; public: Complex(double x, double y) : re(x), im(y){}; void scrie(); }; void main(){ Complex z1(-1., 2.); //obiect initializat Complex z2; //obiect neinitializat . . . } Dac se declar un constructor de iniializare, compilatorul nu mai genereaz un constructor implicit, astfel c pentru obiectele neiniializate (n exemplul de mai sus z2)i tablourile de obiecte se va genera eroare. Putem defini deci doi constructori (i n general orici, avnd n mod evident semnturi diferite), unul implicit i cellalt de iniializare: Complex() : re(0.), im(0.){}; Complex(double x, double y):re(x),im(y){}; Clasa de mai jos definete mai muli constructori: class Data{ int a, l, z; public: Data(int, int, int); Data(int, int); Data(int); Data(); Data(const char*); . . . }; //ctor implicit //ctor de initializare

// // // // //

a, l, z l, z z implicit cu data curenta data reprezentata de sir

Valeriu Iorga

Programare n C / C++

Se prefer nglobarea constructorului implicit n constructorul de iniializare, folosind parametri cu valori implicite. Constructorul de iniializare poate fi folosit drept constructor implicit, dac toi parametrii sunt prevzui cu valori implicite. Complex(double x=0., double y=0.):re(x),im(y){}; Folosirea argumentelor implicite poate reduce numrul de constructori. n exemplul urmtor, n lipsa argumentelor, constructorul asigur iniializarea datei cu valori preluate din obiectul static azi. class Data{ int a, l, z; public: Data(int aa=0, int ll=0, int zz=0); . . . }; Data::Data(int aa, int ll, int zz){ a = aa? aa : azi.a; l = ll? Ll : azi.l; z = zz? zz : azi.z; }; Utilizatorul este obligat s-i defineasc proprii constructori numai n situaiile n care obiectul aloc dinamic spaiu n memorie. Nu pot fi definii mai muli constructori implicii .(fiind suprancrcai, diferiii constructori trebuie s aib semnturi diferite). Un constructor cu un singur argument definete o funcie pentru conversia de tip de la tipul argumentului la tipul clasei. Deci vom putea iniializa un obiect printr-o atribuire de forma: clasa ob=argument; Atriburea de mai sus poate fi considerat ca o conversie implicit. Pentru a o dezactiva, constructorul cu un argument trebuie s fie precedat de cuvntul cheie explicit. Operaia de eliminare a unui obiect din memorie este realizat de o funcie destructor, avnd acelai nume cu al clasei, fr argumente, care nu ntoarce nici o valoare. Pentru a face distincie fa de constructor, numele destructorului ncepe cu ~. Un destructor pentru un obiect este apelat n mod implicit la ieirea din domeniul de definiie al obiectului sau la sfritul programului, pentru obiectele globale sau statice. Sunt foarte rare situaiile n care programatorul apeleaz explicit un destructor. Dac o clas nu are definit destructor, compilatorul genereaz un destructor implicit. Programatorul nu apeleaz n mod explicit constructorii sau destructorul. Constructorii se apeleaz n mod implicit la declararea obiectelor. Destructorul este apelat implicit la ieirea din blocul n care este declarat obiectul. Obiectele create (cu new[])de ctre un constructor explicit trebuiesc distruse (cu delete []) de ctre un destructor definit n mod explicit. La definirea unei funcii constructor sau destructor nu trebuie definit tipul rezultatului ntors de funcie (nici mcar void). Iniializarea obiectului de ctre constructor se poate face prin iniializarea datelor membre cu valorile parametrilor sau prin copierea datelor membre ale unui obiect transmis ca parametru. n acest din urm caz, avem de a face cu un constructor de copiere. Un obiect poate fi iniializat cu o copie a unui alt obiect al clasei sub forma clasa ob1(ob2); De exemplu:

Valeriu Iorga
Complex z1(1., -2.), z2(z1);

Programare n C / C++

O operaie de tipul Clasa ob = Clasa(initializare) prin intermediul constructorului, creaz un obiect i i iniializeaz datele membre. Exemplu: Complex z2 = Complex(1., -2.); are acelai efect cu declaraia precedent. Spre deosebire de acesta: Complex z2; Z2 = Complex(1., -2.); creaz un obiect temporar, pe care l copiaz ntr-un obiect existent. Copierea unui obiect folosind operatorul de atribuire realizeaz o copiere membru cu membru a obiectului surs (din dreapta) n obiectul destinaie (din stnga) Data d=d1; //atribuire Data *pd = new Data(d1); //creare obiect anonim initializat Copia se face membru cu membru. Obiectul ce urmeaz a fi copiat este transmis prin referin. Compilatorul va genera pentru clasa C, un constructor implicit de copiere: C::C(const C&); care realizeaz copierea datelor membru cu membru (copiere superficial). Exemplu: punct p1;// apeleaza constructorul implicit scris de programator // care asigura initializarea la (0, 0) punct p2(2,5); //initializare explicita (ctor de initializare) punct p3(p2); //initializare prin copiere (ctor de copiere) Constructorul implicit de copiere nu funcioneaz corect n caz c obiectul aloc dinamic memorie. n acest caz programatorul trebuie s-i defineasc propriul constructor de copiere, care s realizeze o copiere profund, a datelor indicate de pointeri i nu o copiere a pointerilor. Obiectele clasei pot fi copiate prin atribuire. Copierea se face membru cu membru. Exemplu: Complex z1(-1., 2.); Complex z = z1; Data d1=Data(2004,10,5); Iniializarea este mai eficient dect atribuirea. n cazul atribuirii exist o valoare (veche) a obiectului, care trebuie tears i prin atribuire se copiaz valoarea nou a obiectului din dreapta operatorului de atribuire. Vom considera un exemplu n care se aloc dinamic memorie pentru datele membre. Fie clasa persoana, prevzut cu mai muli constructori i un destructor: class persoana{ private: char* nume; char* adresa; char* cnp; public: persoana(char* n=,char* a=,char* c=); persoana(persoana& p); ~persoana(); }; persoana::persoana(char* n, char* a, char* c){ nume=new char[strlen(n)+1]; strcpy(nume, n); adresa=new char[strlen(a)+1]; strcpy(adresa, a); cnp=new char[strlen(c)+1]; strcpy(cnp, c); };

Valeriu Iorga
persoana::persoana(persoana& p){ nume=new char[strlen(p.nume)+1]; strcpy(nume, p.nume); adresa=new char[strlen(p.adresa)+1]; strcpy(adresa, p.adresa); cnp=new char[strlen(p.cnp)+1]; strcpy(cnp, p.cnp); }; persoana::~persoana(){ delete [] nume; delete [] adresa; delete [] cnp; };

Programare n C / C++

Dac o clas conine date membre constante sau referine, acestea nu pot fi iniializate n corpul constructorului, ci printr-o list de iniializare plasat dup antetul constructorului i separat de acesta prin Constructorii i destructorii sunt apelai implicit la definirea, respectiv distrugerea obiectelor. Obiectele sunt construite n ordinea declarrii lor i sunt distruse n ordine invers declarrii. Clasele care conin membri const i membri referine trebuie s aibe un constructor definit de programator, ntruct referinele trebuiesc iniializate. n absena unor declarri explicite, compilatorul furnizeaz urmtoarele funcii membre: - un constructor implicit - un constructor de copiere - un operator de atribuire - un destructor implicit - un operator de adresare 7. Pointerul this. O funcie care opereaz asupra unei structuri, o va accesa prin intermediul unui parametru pointer la aceast structur. O funcie membru al unei clase, apelat dintr-un obiect, pentru a accesa membrii date ai obiectului, va avea un parametru implicit pointer la obiect. Acest pointer poart numele de pointerul this, i se declar ntr-o clas C ca: C* const this; Fiind cuvnt cheie, el nu poate fi declarat explicit; fiind un pointer constant el nu poate fi modificat. Referirea la datele membre x0 i y0 se face prin intermediul acestui pointer ascuns ca this>x0 i this->y0. O funcie membru care returneaz un obiect o poate face prin return *this (returnarea unui pointer la obiect se face prin return this). 8. Membri statici ai claselor. n fiecare obiect, pentru datele membre nestatice se creaz copii. Pentru funciile membre exist o copie unic. Pentru datele membre statice exist o singur copie care va fi partajat de ctre toate obiectele. Funciile membre statice sunt accesibile numai n fiierul n care sunt definite, fiind independente de obiecte (instanele claselor). O funcie static poate fi apelat:

ca funcie membr a unui obiect independent de obiect, folosind operatorul de rezoluie.

Pointerul this nu poate fi folosit de ctre funcia static, deoarece nu i este transmis, aadar funcia static nu poate accesa dect date membre statice i date globale.

10

Valeriu Iorga

Programare n C / C++

Clasa Data depinde de variabila static azi. Aceasta va aparine clasei, dar nu i obiectelor clasei. class Data{ int a, l, z; static Data azi; //data membra statica public: Data(int aa=0, int ll=0, int zz=0); . . . static void set_data_crta(int aa, int ll, int zz); }; Data::Data(int a = aa? aa : l = ll? ll : z = zz? Zz : }; aa, int ll, int zz){ azi.a; azi.l; azi.z;

Funcia set_data_crta() permite modificarea datei curente, care iniializeaz un obiect neiniializat. La definirea unui membru static nu se mai repet cuvntul static. void Data::set_implic(int a, int l, int z){ azi = Data(a, l, z); }; 9. Funcii membre constante. Funciile membre care nu modific starea obiectului se declar ca funcii constante (funcii const), punnd dup lista de parametri cuvntul cheie const. Compilatorul va sesiza orice ncercare de modificare a obiectului din funcia const. Funciile membre apelate din obiectele constante pot fi numai funcii constante. Dac funcia membr const este definit n afara clasei, este necesar sufixul const n definiie. Exemplu: class Data{ int a, l, z; public: int zi()const {return z;}; int luna()const {return l;}; int an()const; }; inline int Data::an()const{ return a;}; Nu este posibil declararea unei constante simbolice n interiorul unei clase. Astfel: class Vector{ const int N=10; double x[N]; . . . } nu funcioneaz corect deoarece declararea clasei descrie obiectul, dar nu l creaz. Sunt posibile dou soluii: - se declar o enumerare n interiorul clasei, care furnizeaz la nivelul clasei nume simbolice pentru constante ntregi : class Vector{ enum{ N=10 }; double x[N];

11

Valeriu Iorga
. . . } - se creaz o constant static, partajat de toate obiectele Vector class Vector{ static const int N=10; double x[N]; . . . } 10. Funcii care returneaz referine.

Programare n C / C++

Pentru clasa complex, am definit funciile care asigur accesul partea real, respectiv imaginar a unui numr complex,: double real(){ return re; }; double imag(){ return im; }; Dac am dori modificarea prii reale a unui numr complex printr-o atribuire de forma: z.real()=5.; constatm c funcia astfel definit nu poate aprea n partea stng a unei atribuiri (nu este o L-valoare). Acest neajuns se remediaz impunnd funciei s returneze o referin la obiect, adic: double& real(){ return re; }; Funciile de actualizare a datei ad_a(), ad_l(), ad_z() nu ntorc valori. Pentru asemenea funcii este util s ntoarcem o referin la obiectul actualizat, astfel nct operaiile s poat fi nlnuite de forma: d.ad_a(1).ad_l(1).ad_z(1); Funciile se declar cu valoare de ntoarcere referin la Data: class Data{ Data& ad_a(int); Data& ad_l(int); Data& ad_z(int); }; Data& ad_a(int n){ if(z==29 && l==2 && !bisect(a+n)){ z=1; l=3; }; a += n; return *this; } ntr-o funcie membru nestatic this este un pointer la obiectul din care s-a apelat funcia membru. Nu este posibil s prelum adresa lui this i nici s o modificm. Cele mai multe referiri la this sunt implicite. Orice referire la un membru nestatic din interiorul clasei folosete n mod implicit pe this pentru a obine membrul din acel obiect. O clas conine n mod uzual: un constructor, funcii pentru examinarea obiectelor (funcii de acces), funcii pentru manipularea obiectelor, operaii de copiere, etc. 11. Probleme.

12

Valeriu Iorga

Programare n C / C++

1. Definii i implementai clasa Cerc, avnd ca dat membru Raza, un constructor i ca funcii membre Aria i Circumferinta. 2. Definii i implementai clasa Cilindru, avnd ca date membre Raza i Inaltimea cilindrului i ca funcii membre: un constructor, Aria i Volumul. 3. Definii i implementai clasa Televizor, avnd ca date membre: Volumul i Canalul i ca funcii membre: un constructor, Pornire, Oprire, Schimbare_Volum, Schimbare_Canal. 4. Definii i implementai clasa Dreptunghi, avnd ca date membre: Lungimea i Laimea i ca funcii membre: un constructor, SetLungime, SetLaime, GetLungime, GetLaime, Arie i Perimetru. 5. Specificai, proiectai i implementai o clas care poate fi folosita ntr-un program pentru a simula o combinaie de deschidere a unui seif. Seiful are un buton circular cu numere de la 0 la 39 i pentru deschiderea lui este necesar formarea unei combinaii de 3 numere, fie acestea x, y i z. Pentru deschiderea seifului, se roteste n sens orar butonul pn la formarea numrului x, apoi se roteste n sens antiorar pn la formarea lui y, i n final se formeaz z prin rotire n sens orar. Clasa Seif va avea un constructor, care iniializeaz combinaia codului de deschidere cu 3 numere date ca argumente (ca argumente implicite se iau 0,0,0). Sunt prevzute urmtoarele funcii membre: - modificarea codului de deschidere la o noua combinaie de 3 numere - rotirea butonului ntr-o directie dat, pn cnd se formeaz un numr dat - nchiderea seifului - ncercarea de a deschide seiful - testarea strii seifului (deschis sau nchis) - indicarea combinaiei de cod ncercate pentru deschidere. 6. Specificai, proiectai i implementai o clas Punct3, folosite pentru reprezentarea punctelor (prin 3 coordonate x,y,z) n spaiul 3-dimensional. Asigurai urmtoarele funcii membre: - constructor pentru setarea unui punct ntr-o poziie specificat (implicit n 0,0,0) - mutarea unui punct cu valori specificate pentru cele 3 direcii - aflarea coordonatelor unui punct - rotaia unui punct cu un unghi specificat de-a lungul uneia dintre axele x,y sau z. Coordonatele noului punct x',y',z' sunt: rotaie n jurul axei x: x'=x y'=y*cos(t)-z*sin(t) z'=y*sin(t)+z*cos(t) rotaie n jurul axei y: x'=x*cos(t)+z*sin(t) y'=y; z'=-x*sin(t)+z*cos(t) rotaie n jurul axei z: x'=x*cos(t)-y*sin(t) y'=x*sin(t)+y*cos(t) z'=z Se vor defini ca funcii nemembre: - distana ntre doua puncte

13

Valeriu Iorga

Programare n C / C++

- testul dac 2 puncte se confund, prin redefinirea operatorului == - afiarea coordonatelor unui punct la ieirea standard, prin suprancrcarea operatorului << Se va defini ca funcie prieten citirea coordonatelor unui punct de la intrarea standard, prin suprancrcarea operatorului >> 7. Proiectai i implementai o clas Aleator, care genereaz o secven de numere ntregi pseudoaleatoare, folosind metoda congruenei liniare. In aceast metod se folosesc 4 ntregi: smna, nmulitorul, incrementul i modulul. cu formula: (samanta * nmultitor + increment) % modul se genereaz cte un numr aleator, care devine smn. n acest mod se genereaz " modul" numere diferite. Constructorul clasei are ca argumente: smna iniial, nmulitorul,incrementul i modulul. Se vor prevedea funcii membre pentru: - schimbarea smnei - generarea urmtorului numr din secvena de numere aleatoare 8. Definii i implementai clasa Calendar avnd ca date membre: An, Luna, Zi, NumeZi (enumerarea de Luni pn Duminica) i ca funcii membre: -un constructor -obinerea datei curente -modificarea datei curente -incrementarea datei curente -afiarea datei curente. Se va defini o functie prieten pentru citirea datei curente. Se vor defini de asemeni funcii nemembre cu 2 parametri date calendaristice: - Anterior care ntoarce rezultatul boolean true/false dup cum data argument 1 este naintea sau dup data argument 2 i - Interval care ntoarce numrul de zile cuprins ntre cele dou date argumente.

14

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