Sunteți pe pagina 1din 48

PROGRAMAREA ORIENTAT PE OBIECTE

NDRUMAR DE LABORATOR

Liviu erbnescu UNIVERSITATEA HYPERION

LISTA LUCRRILOR

1. Iniiere ntr-un mediu de programare. Structura unui program C++. 2. Noiunea de clas i obiect. Operatori specifici C++. 3. Clase i moteniri. Clase de baz virtuale 4. Constructori i destructori 5. Modificatorii i specificatorii de acces 6. Date i funcii de tip friend i statice 7. Polimorfism, funcii virtuale 8. Suprancrcarea operatorilor 9. Fluxuri de intrare/ieire.Obiecte standard 10. Fluxuri de intrare/ieire.Operatii de intrare/iesire cu fisiere 11. Tratarea excepiilor 12. Utilizarea claselor wxWidgets (I) 13. Utilizarea claselor wxWidgets (II) 14. Teste.

LABORATORUL NR.1 INIIERE NTR-UN MEDIU DE PROGRAMARE. STRUCTURA UNUI PROGRAM C++ Scop: 1. Familiarizarea cu mediul integrat CodeLite. 2. nelegerea structurii unui program scris n limbajul C++. 3. nelegerea bibliotecilor ce utilizeaz programarea orientat pe obiecte.

Consideraii teoretice: Mediul integrat - OpenSource - CodeLite Un spaiu de lucru (workspace) detine un numar de proiecte, de exemplu, acestea pot avea legtur unele cualtele sau nu Crearea unui spaiu de lucru se realizeaz prin selectarea " "Workspace | Create new Workspace"" Un proiect (project) poate avea va rezultat n urma compilrii i apoi a link-editrii un executabil, o bibliotec dinamic (*.DLL), o bibliotec static(*.LIB), etc. Proiectul n sine conine toate informaiile necesare pentru a produce o aplicaie de un anumit tip (aplicaie consol, aplicaie grafic ce utilizeaz un anumit set de controale vizuale, aplicaie cu obiecte grafice, etc). Fiierul ce conine informaii despre spaiul de lucru se numete <workspace-name>.workspace Fiierul ce conine informaii despre proiect este <project-name>. prj Pentru crearea unui proiect nou se va utiliza opiunea GUI (Graphics User Interface).

Structura unui program C++ Un programC++ cuprinde urmtoarele elemente pricipale:


operatori (aritmetici, logici, etc) instruciuni (de decizie, de parcurgere a unei bucle, etc) funcii (apelate din cadrul bibliotecilor sau definite de utilizator) variabile i constante funcia main()

Textul unui program poate fi scris ntr-un fiier sau n mai multe fiiere. Un program va avea o singur funcie main() indiferent dac este scris ntr-un singur fisier sau n mai multe fiiere. Programul compilat i linkeditat va incepe ntodeauna prin lansarea n execuie a instruciunilor i funciilor din cadrul lui main(). Prin ieirea din funcia main() se ncheie i execuia programului.

Desfurarea lucrrii: 1. Lansarea mediului CodeLite, i studierea principalelor componente ale interfeei acestuia 2. Crearea unor spaii de lucru 3. Crearea unui proiect pentru aplicaie consol 4. Compilarea unui exemplu. Modificarea setrilor implicite de compilare. 5. Executarea separat aLink-editrii pentru o aplicaie. Modificarrea setrilor implicite pentru link-editare 6. Adugarea bibliotecilor cu clase. 7. Recompilarea (avnd i biblioteci cu clase) 8. Relinkeditarea .

LABORATORUL NR.2 NOIUNEA DE CLAS I OBIECT. OPERATORI SPECIFICI C++ Scop: 1. nelegerea noiunilor de clas i obiect 2. nelegerea operatorilor specifici C++ Consideraii teoretice:
CONCEPTE FUNDAMENTALE Ideea de baza de la care pleaca programarea orientata obiect este de a grupa structurile de date cu operatiile care prelucreaza respectivele date. Un asemenea ansamblu poarta denumirea de obiect sau clasa (tipul datei). Proiectarea de programe utilizand clase se numeste programare orientat pe obiecte (OOP- Object Oriented Programming). Notiuni fundamentale: Datele (membrii) i funciile (membrele / metodele) unei clase Datele sunt reprezentate prin declaraiile variabilelor din cadrul clasei. n cadrul unei clase pot fi declarate inclusiv variabile de tip structur sau de tip clas. Date + Metode = Obiect sau Clas (tipul datei) Principiul ncapsulrii (ascunderea informaiei ce st la baza realizrii clasei): accesul la datele membre se poate face numai prin intermediul setului de metode asociat. Obiectul este caracterizat complet prin metodele asociate. O parte din metode vor fi utilizate de cel ce utilizeaz clasa n cadrul aplica iilor, iar alt parte va fi invizibil pentru utlizatorul final (att codul ct i apelul acestora). Conform principiului ncapsulrii utilizatorul nu are acces la date ci numai la metodele pe care dezvoltatorul clasei le-a lsat pentru a putea fi apelate.
Operatorii specifici C++ OPERATORUL SIMBOLU L rezoluie / indicator acces valoare valoare new delete this :: .* ->* new
delete

FORMA ::a ::f() OB.*a OB->*a new tip


delete a delete a[]

Operaia realizat
- acceseaz variabilele globale chiar dac au acelai nume cu cele locale - acceseaz membrii/membrele claselor - ntoarce valoarea (OB valoare) - ntoarce valoarea (OB pointer) aloc memorie. ex ptr. un vector de 10 ntregi: new int[10], ntoarce NULL n caz de eec altfel ntoarce adresa alocat elibereaz zona de memorie arat adresa obiectului curent (n care ne aflm) iar *this este valoarea obiectului curent

this

this/ *this

Desfurarea lucrrii: 1. Se execut exemplele corespunztoare din seciunea TESTE

LABORATORUL NR.3 CLASE I MOTENIRI. CLASE DE BAZ VIRTUALE Scop: 1. negerea motenirii claselor 2. Utilizarea funciilor i a claselor de baz virtuale Consideraii teoretice:
Procedeul de derivare permite definirea unei clase noi, numit clas derivat, care motenete propietile (membri + membre) unei clase deja definite, numit clas de baz, pe care le completeaz cu propieti (membri+membre) noi. Clasa de baz nu este afectat i nu trebuie recompilat, declaraia (fiierul header) i codul obiect (fiier obj / dll/ lib) ale clasei de baz sunt suficiente pentru crearea unei clase derivate. Dintr-o clas (numit clas de baz) pot fi derivate mai multe clase, iar fiecare clas derivat poate servi ca baz pentru alte clase derivate. Astfel se realizeaz o ierarhie de clase. Pornind de la clase simple i generale, fiecare nivel al ierarhiei acumuleaz caracteristicile (membri +membre) claselor "printe" (baz) i le adaug un anumit grad de specializare. n cazul n care o clas motenete proprietile mai multor clase avem motenire multipl. Sintaxa declaraia clasei derivate n cazul unei singure clase de baz: class nume_clasa_derivata : modificator_acces nume_clas_baza iar n cazul mai multor clase de baz (motenire multipl): class nume_clasa_derivata : modificator_acces nume_clas_baza_1 [<, modificator_acces nume_clas_baza_n >]

Funciile constructor, destructor i mecanismul de motenire Clasa de baz, clasa derivat, sau ambele, pot avea funcii constructor i/sau destructor. Cnd o clas de baz i una derivat conin att funcii constructor ct i destructor, cele constructor sunt executate n ordinea derivrii iar funciile destructor sunt executate n ordine invers. Adic duncia constructor din clasa de baz este executat naintea celei din clasa derivat iar destructorul unei clase derivate este executat naintea celui din clasa de baz. Cnd se expliciteaz costructorul din clasa derivat trebuie s se specifice care din constructorii clasei de baz este apelat ( constructorii difer ntre ei - n momentul declarrii - prin numrul i tipul argumentelor) De asemenea, primele argumente din constructorul clasei derivate trebuie s coincid cu argumentele constructorului ales din clasa de baz. Sintaxa este: nume_clas_derivat::nume_clas_derivat(lista_argumente_1,lista_argumente_2):nume_clas a_baza (lista_argumente_1v) { corpul constructorului } unde: lista_agumente_1 este lista de argumente a constructorului bazei (tipuri +variabile), lista_agumente_1v este lista de argumente a constructorului bazei (variabile) iar lista_agumente_2 este lista de argumente a suplimentar, specific constructorului clasei derivate (tipuri +variabile) iar n cazul motenirii multiple sintaxa este: nume_clas_derivat::nume_clas_derivat (lista_argumente_1, lista_argumente_2):nume_clasa_baza_1(lista_argumente_11v)[<, nume_clasa_baza_n(lista_argumente_n1v) >] { corpul constructorului }
unde lista_argumente_n1v sunt incluse n lista_argumente_1v

Clase de baz virtuale Presupunem ca avem o clas BAZA i dou clase ce deriv din BAZA, numite DER1 i DER2. Apoi din DER1 i DER2 derivm o alt clas denumit DER12 . Deci, clasa DER12 motenete de dou ori clasa BAZA, o dat prin DER1 i o dat prin DER2. Acest lucru determin o ambiguitate cnd clasa DER12 vrea s aib acces la datele din clasa BAZA. (de ex. pot fi date din clasa BAZA, modificate n cadrul clasei DER1

sau modificate n cadrul clasei DER2 - att DER1 ct i DER2 au cte o copie a clasei BAZA). Pentru a rezolva aceast ambiguitate, C++ include un mecanism prin care doar o copie a clasei BAZA va fi inclus n clasa DER12. Acesta const n declararea clasei BAZA ca fiind clasa de baz virtual. Se utilizeaz cuvntul cheie virtual naintea modificatorului de acces. (ex: class DER1: virtual public BAZA {}; class DER2: virtual public BAZA {}; class DER12: public DER1, public DER2 {};
#include <stdio.h> #include <iostream> //mostenire de tip - diamant class A{ int a1,a2; public: A() {a1=0;a2=0;} A(int a1_,int a2_) {a1=a1_;a2=a2_;} void afis() {std::cout<<"/n a1="<<a1<<" a2="<<a2;} }; class B: public virtual A {int b1,b2; public: B():A() {b1=0;b2=0;} B(int a1_,int b1_):A(a1_,0) {b1=b1_; b2=0;} void afis1() {std::cout<<"/n b1="<<b1<<" b2="<<b2;} }; class C: virtual public A {int c1,c2; public: C():A() {c1=0;c2=0;} C(int c1_,int c2_): A() {c1=c1_; c2=c1_;} void afis1() {std::cout<<"/n c1="<<c1<<" c2="<<c2;} }; class D: public B, public C { int d1,d2; public: D():B(),C() {d1=0;d2=0;} }; int main(int argc, char **argv) { D x1; x1.afis(); int m; std::cin>>m;//astapta o tasta return 0; } // cuvantul cheie virtual permite eliminarea duplicatelor clasei A

Desfurarea lucrrii: 1. Se ruleaz exemplele din seciunea teoretic 2. Se continu cu exemplele corespunztoare din seciunea TESTE

LABORATORUL NR.4 CONSTRUCTORI I DESTRUCTORI

Scop: 1. Utilizarea constructorilor 2. Utilizarea destructorilor 3. negerea ordinii de apel a constructorilor 4. nelegerea ordinii de apel a destructorilor Consideraii teoretice: CONSTRUCTORI: Constructorul se apeleaz automat la crearea fiecrui obiect al clasei, creare de tip static, automatic sau dinamic; Funcia constructor are acelai nume cu al clasei (case sensitive); O clas poate avea mai muli constructuri, ei se deosebesc prin numrul i tipul argumentelor; In cazul n care nu se scrie nici un constructor se va apela automat un constructor, fr argumente i de tip public. Dac utilizatorul declar cel puin un constructor atunci compilatorul nu mai genereaz acest constructor implicit; Exist i un constructor implicit de copiere ce iniializeaz obiectul curent cu datele (membrii) din alt obiect de acelai tip (aparinnd aceleiai clase) El are forma nume_clas(nume_clasa &)i poate fi redefinit; Constructorii nu ntorc valori; Constructorii sunt apelai automat dup ce se se aloc memorie (automatic sau static) pentru obiectele membru (date membru /membrii) DESTRUCTORI: Destructorul este apelat automat cnd obiectul respectiv i nceteaz existena n memorie. Destructorul are acelai nume cu al clasei i se declar cu operatorul ~ inainte; Utilizatorul nu va putea apela explicit destructorul unei clase; Destructorul nu preia i nu ntoarce valori; O clas are un singur destructor; In cazul n care nu este declarat nici un destructor se va apela unul implicit; Destructorii sunt apelai automat naintea eliberrii memoriei alocat automatic sau static pentru datele membru. Explicitarea funciilor membre (inclusiv a constructorilor i destructorilor) se poate face fie n interiorul declaraiei clasei, fie n exteriorul clasei prin utilizarea operatorului rezoluie " :: ". Funciile din cadrul unei clase se pot clasifica n: - constructori; - destructori; - funcii normale de acces; - funcii de tip prieten (friend); - funcii virtuale; - funcii statice;

- funcii de tipul operator.


Exemplu:
#include <stdio.h> #include <iostream> using namespace std; class A3 { public: int a1; protected: int a2; private: int a3; public: A3(int a1_) { a1=a1_;a2=0;a3=0;//cout<<"\n constructor A3(a1)<<a1:"<<a1; } A3(int a1_,int a2_,int a3_) {a1=a1_;a2=a2_;a3=a3_;} void afis_a() {cout<<"\nClass A3: a1="<<a1<<" a2="<<a2<<" a3="<<a3;} };

class B3:protected A3 {int b3; protected: int b2; public: int b1; B3(int a1_, int b1_):A3(a1_) {b1=b1_;b2=0;b3=0; //cout<<"\n constructor B3(a1,b1)<<b1:"<<b1; } B3(int a1_,int a2_,int a3_,int b1_,int b2_,int b3_):A3(a1_,a2_,112) {b1=b1_;b2=b2_;b3=b3_;} void afis_b() {// cout<<"\nClass B3 a1="<<a3; afis_a(); cout<<" b1="<<b1<<" b2="<<b2<<" b3="<<b3;} }; int main(int argc, char **argv) { //A3 x(4); //x.afis_a(); //B3 y(2,7); //y.afis_b(); B3 z(1,2,3,4,5,6); //z.afis_a(); z.afis_b(); getchar(); return 0; }

Exemplu:
#include <stdio.h> #include <iostream> #include <string.h> using namespace std;

class A{ protected: char *sir; unsigned long dim; public: A(unsigned long dim1); A(char *); void prel(); void afis(); ~A(); }; A::A(unsigned long dim1) { dim=dim1; if((sir=new char[dim])==NULL) cout<<"Memorie insuficienta"; memset(sir,0,dim*sizeof(char)); } A::A(char* sir1) { strcpy(sir,sir1); dim=strlen(sir); } A::~A() {

if(sir) delete[] sir; } void A::prel() { //cin>>sir; scanf("%s",this->sir); } void A::afis() { cout<<"\n Sirul este:"<<sir; }

class A1:public A { char *sir_ord_cresc; public: A1(unsigned long dim1):A(dim1) { sir_ord_cresc = new char[dim]; } A1(char * sir1):A(sir1) {sir_ord_cresc = new char[dim];} bool cauta_caracter(char x) { for(int i=0;i<dim;i++) if(sir[i]==x) return true; return false; } void ordoneaza_cresc() {bool ordonat;int i; strcpy(sir_ord_cresc,sir); do{ for(i=1,ordonat=true;i<dim;i++)

} }while(!ordonat); }

if(sir_ord_cresc[i-1]>sir_ord_cresc[i]) { sir_ord_cresc[i-1]=sir_ord_cresc[i-1]^sir_ord_cresc[i]; sir_ord_cresc[i]=sir_ord_cresc[i-1]^sir_ord_cresc[i]; sir_ord_cresc[i-1]=sir_ord_cresc[i-1]^sir_ord_cresc[i]; ordonat=false;

/*void afis() { cout<<"\n Sirul ordonat este:"<<sir_ord_cresc; }*/ }; int main(int argc, char **argv) { A1 x(40); x.prel(); //x.afis(); x.ordoneaza_cresc(); x.afis(); //getchar(); int m; cin>>m; return 0; }

Desfurarea lucrrii: 1. Se ruleaz exemplul din seciunea teoretic 2. Se continu cu exemplele corespunztoare din seciunea TESTE

LABORATORUL NR.5 MODIFICATORII I SPECIFICATORII DE ACCES Scop: 1. nelegerea noiunilor de privite, protected i public 2. Utilizarea modificatorilor de acces n cadrul constructorilor 3. Utilizarea specificatorilor de acces. 4. nelegerea drepturilor de acces n condiiile n care avem att modificatori de acces ct i specificatori de acces Consideraii teoretice
Datele (membrii) i membrele (funciile) din interiorul unei clase pot avea urmtorii specificatori de acces: - public: datele/membrele pot fi accesate de oriunde, chiar si din afara clasei; - protected: datele/membrele dintr-o clas de baz pot fi vazute n interiorul claselor derivate dar nu i n afara acestora; - private: datele/membrele dintr-o clas nu sunt vzute dect n interiorul clasei. Implicit toate datele i metodele din cadrul unei clase sunt private. Daca constructorii nu ar fi declarai cu specificatorul de acces public nu am putea avea obiecte de tipul clasei respective n afara clasei.

Modificatorii de acces Specificatorul de acces din clasa de baz private protected public private protected public
Exemplu //main.h
class P_ABC { protected: char *sir_c,tip; long *sir_l; double *sir_d; short dim;

Modificator de acces private private private public public public

Accesul motenit de clasa derivat inaccesibil private private inaccesibil protected public

Accesul din exterior inaccesibil inaccesibil inaccesibil inaccesibil inaccesibil accesibil

P_ABC(short dim1, char tip1); //'c' , 'l', 'd' ~P_ABC();

virtual void afisare()=0; virtual void citire()=0; //functii virtuale pure ==> clasa de baza virtuala ==> NU se pot instanta direct obiecte ale acestei clase }; class A : protected P_ABC { protected: //se pot apela in clasele derivate char *sir; public: //se pot apela in afara clasei si in afara ierarhiei de clase A(short dim1); A(char*); ~A(); char* obtine_sir(); void afisare(); void citire(); };

class B : public P_ABC { protected: long *sir; public: B(short dim1); long* obtine_sir(); void afisare(); void setare(int i, long val) {sir[i]=val;} void citire(); }; class Z { int x,y; protected: Z(int x1,int y1) {x=x1;y=y1;} }; //mostenire multipla class AZ: public A, protected Z

{ public: AZ(short dim1,char valinit_c); }; //main.cpp #include <stdio.h> #include <string.h> #include <iostream> #include <main.h> using namespace std; P_ABC::P_ABC(short dim1,char tip1) { dim=dim1; sir_c=NULL;sir_d=NULL;sir_l=NULL; tip=tip1; if(tip=='c') sir_c=new char[dim+1]; // +1 ptr. terminatorul de sir '/0' if(tip=='l') sir_l=new long[dim]; if(tip=='d') sir_d=new double[dim]; // if(sir_c==NULL &&) {cout<<"Memorie insuficienta";return;} } P_ABC::~P_ABC() { if(sir_c) delete[] sir_c; if(sir_l) delete[] sir_l; if(sir_d) delete[] sir_d; } A::A(short dim1):P_ABC(dim1,'c') { //preia dimensiunea sirului //dim=dim1; //aloca memorie ptr. sir // sir = new char[dim+1]; // +1 ptr. terminatorul de sir '/0' // if(sir==NULL) {cout<<"Memorie insuficienta";return;} // echivalent cu: if(!(sir= new char[dim])) {{cout<<"Memorie insuficienta";return;} sir=sir_c; } A::A(char* sir1):P_ABC(strlen(sir1),'c') { //dim=strlen(sir1); //if(!(sir= new char[dim])) {cout<<"Memorie insuficienta";return;} sir=sir_c; //strcpy(sir,sir1); for(int i=0;i<dim;i++) sir[i]=sir1[i]; } A::~A() { //if(sir) delete[] sir; } char* A::obtine_sir() {return sir;} void A::afisare() {cout<<"\n Sirul din clasa A este:"<<sir;}

void A::citire() { cin>>sir;} B::B(short dim1):P_ABC(dim1,'l') {sir=sir_l;} long* B::obtine_sir() {return sir;} void B::afisare() {cout<<"\n Sirul din clasa B este:"<<sir[0];} void B::citire() { cin>>sir[0];} /*AB::AB(char valinit_c, long valinit_l):A(5),B(9) { for(int i=0;i<dim;i++)

}*/ AZ::AZ(short dim1,char valinit_c):A(dim1),Z(2,3) { for(int i=0;i<dim;i++) sir[i]=valinit_c; }

int main(int argc, char **argv) { A *s2,s1("abcd"); B *s3; //P_ABC d(4,'c'); eroare : clasa de baza abstracta -- nu se vor instantia obiecte s2=new A("1234"); s1.afisare(); s2->afisare(); s3=new B(2); //s3->citire(); s3->setare(0,45); s3->afisare(); AZ t(5,'k'); t.afisare(); int m; cin>>m; //asteapta o tasta return 0; }

Desfurarea lucrrii: 1. Se ruleaz exemplele din seciunea teoretic 2. Se continu cu exemplele corespunztoare din seciunea TESTE

LABORATORUL NR.6 DATE I FUNCII DE TIP FRIEND I STATICE Scop: 1. nelegerea tipului de dat friend pentru o clas 2. nelegerea tipului de dat static pentru membrii unei clase 3. Utilizarea instanierii claselor cu metode statice Consideraii teoretice: Funcii de tipul "prieten" (friend) O funcie de tip friend (prieten) este o funcie care nu este membr a clasei i are acces la toi membrii clasei. n interiorul clasei, ea se declar prin scrierea cuvntului cheie friend naintea declararaiei propiu-zise a funciei. O clas ale crei funcii sunt, n totalitate, friend pentru alt clas se numese clas prieten a acelei clase. O funcie prieten, este o funcie declarat n afara clasei (nu aparine clasei) i creia i se d acces la toate datele din cadrul clasei. n interiorul clasei este declarat cu cuvntul cheie friend n fa. Adresa obiectului curent este dat de operatorul this. MEMBRII STATICI Un tip aparte de membri ai unei clase sunt membrii statici. Atat functiile membru cat si datele membru (atributele) unei clase pot fi declarate static. Variabile Membru Statice Daca declaratia unei variabile membru este precedata de cuvantul-cheie static, atunci va exista o copie unica a acelei variabile care va fi folosita in comun de catre toate obiectele instantiate din clasa respectiva. Spre deosebire de variabilele membru obisnuite, pentru variabilele statice nu sunt create copii individuale ale acestora pentru fiecare obiect in parte. Accesarea unei variabile statice se face folosind numele clasei si operatorul de specificare a domeniului ("::"). Cand se declar o data membru ca fiind static intr-o clasa, ea nu este nca alocat. Prin declarare nu se aloca memorie, acest lucru se realizeaz n exteriorul clasei. Pentru a defini o variabila membru statica, aceasta trebuie prevazuta cu o definire globala undeva in afara clasei. Variabilele statice (ca si functiile membru statice de altfel) pot fi utilizate indiferent daca exista sau nu instante ale clasei respective. De aceea, initializarea unei variabile statice NU poate cadea in sarcina constructorilor clasei (constructorii, se stie, se executa doar la momentul generarii unei instante). Constructorii pot, insa, sa modifice valorile variabilelor statice (de exemplu, pentru a contoriza numarul instantelor unei clase, create la executia unui program). Variabilele membru statice sunt folosite cel mai adesea pentru a asigura controlul accesului la o resursa comuna (ex. scrierea intr-un fisier). Acest tip de variabile se mai folosesc si pentru a stoca informatii comune unei intregi clase de obiecte. Functii Membru Statice Si functiile membru pot fi declarate ca statice. In C++ o functie membru statica se comporta asemanator cu o functie globala al carei domeniu este delimitat de clasa in care este definita. Operatorul "this" Cuvntul cheie this arat adresa obiectului curent (n care ne aflm) iar *this este valoarea obiectului curent.

//functii friend #include <stdio.h> #include <iostream> class A {int a1; friend void aduna(A& x1, A& x2); public: A() {a1=0;} A(int a1_) {a1=a1_;} }; void aduna(A& x1, A& x2) { int rez; rez=x1.a1 +x2.a1; std::cout<<"\n x1.a1+x2.a1="<<rez; } int main(int argc, char **argv) { A s(3),t(5); aduna(s,t); int m; std::cin>>m; return 0; } //variabile de tip static #include <stdio.h> #include <iostream> // definim variabila cnt pentru a contoriza numarul de obiecte de tip A existente class A { int a1; public: static int cnt; A() {a1=0; cnt++;} A(int a1_) {a1=a1_;cnt++;} ~A() {cnt--;} static void afis() {std::cout<<"\n nr.obiecte:"<<cnt;} }; int A::cnt=0; //aici se declara cnt -- variabila nu se afla in obiectele instantiate int main() { A x[10];//vector cu 10 obiecte de tip A, instantiate cu constructorul implicit () { A y[5], z(4); std::cout<<"\n1:"; A::afis(); } std::cout<<"\n2:"; A::afis(); int m; std::cin>>m; return 0; }

Desfurarea lucrrii: 1. Se ruleaz exemplele din seciunea teoretic 2. Se continu cu exemplele corespunztoare din seciunea TESTE

LABORATORUL NR.7 POLIMORFISM, FUNCII VIRTUALE Scop: 1. nelegerea noiunii de polimorfism 2. Utilizarea funciilor virtuale Consideraii teoretice:
Funciile virtuale sunt folosite pentru implementarea obiectelor polimorfice. Obiectele polimorfice se careacterizeaz prin faptul c folosind aceeai form de apel pentru funciile membre realizm operaii diferite. Funciile viruale implementeaz filozofia "o singur interfa, mai multe metode", care pune n eviden "poli morfism-ul" Variabile de tip pointer care puncteaz la clasele derivate Presupunem dou clase, denumite:BAZA i DERIVATA, unde clasa DERIVATA motenete clasa BAZA. n aceste condiii, urmtoarele instruciuni sunt valabile: BAZA *p; // pointer-ul care puncteaz la clasa baza BAZA OB_TIP_BAZA; //un obiect de tip BAZA DERIVATA OB_TIP_DER; // un obiect de tip DERIVATA // pointer-ul p poate puncta (prelua adresa) la obiecte de tip BAZA p=&OB_TIP_BAZA; // p preia adresa lui OB_TIP_BAZA // p poate puncta la obiecte derivate p=&OB_TIP_DER; // p preia adresa lui OB_TIP_DER Un pointer al clasei de baz poate puncta la un obiect din clasa derivat, fr a genera vreo eroare, invers nu este valabil. Prin acest pointer putem avea acces doar la membrii clasei derivate care au fost motenii de la clasa de baz. Funcii virtuale O funcie virtual este o funcie membr a unei clase, care se declar n interiorul unei clase de baz i se redefinete (modific) n clasele derivate. Pentru a crea o funcie virtual, trebuie s utilizm cuvntul cheie virtual, nainte de declaraia funciei. La nivelul fiecrei clase funciile virtuale mplementeaz cod specific clasei respective, ns ele au acelai nume, aceeai list de parametrii i ntorc aceelai tip de dat. Cnd un pointer al clasei de baz puncteaz la o funcie virtual din clasa derivat, i aceasta este apelat prin intermediul acestui pointer, compilatorul determin care versiune (care din codurile/ care explicitare) a funciei trebuie apelat, innd cont de tipul obiectului (care clas) la care puncteaz acel pointer. Adic tipul obiectului (clasa ) la care puncteaz determin versiunea funciei virtuale care va fi executat. O funcie virtual poate fi declarat i numai formal, ea nerealiznd nimic concret, ea fiind declarat doar pentru ca n clasele derivate s fie declarat i explicitat. O astfel de funcie virtual, fr cod/explicitare se numete funcie virtual pur. Sintaxa pentru o funcie virtual pur este: virtual tip nume_funcie(list_de_parametri)=0; O clas ce conine o funcie virtual pur se numete clas abstract. Clasele abstracte sunt utilizate doar pentru a fi motenite. Nu se pot intania obiecte pentru clase abstracte.
//polimorfism #include <stdio.h> #include <iostream> using namespace std;

class Patrulater { protected: double laturi[4]; public: Patrulater(double l1=0.0, double l2=0.0, double l3=0.0, double l4=0.0) {laturi[0] = l1; laturi[1] = l2; laturi[2] = l3; laturi[3] = l4; } virtual double perimetru() { return laturi[0]+ laturi[1]+laturi[2]+laturi[3]; } virtual double arie() {}; }; class Dreptunghi : public Patrulater { public: Dreptunghi(double l1=0.0, double l2=0.0) : Patrulater(l1,l2,l1,l2) {} double perimetru() { return 2*(laturi[0]+laturi[1]); } double arie() { return laturi[0]* laturi[1]; } }; class Patrat : public Patrulater { public: Patrat(double l1 = 0.0) : Patrulater(l1,l1,l1,l1) {} double perimetru() { return 4*laturi[0]; } double arie() { return laturi[0]*laturi[0]; } }; // *colectie[] === **colectie, prima scriere este sugestiva ptr. vector de pointeri void CalculeazaPerimetre(Patrulater *colectie[]) {// for-ul se executa atata timp cat elem != NULL // elem este un pointer de parcurgere de tip Patrulater // la fiecare iteratie se trece la adresa urmatoare for(Patrulater *elem = *colectie; elem ; elem = *(++colectie)) printf("\n %f", (*elem).perimetru());// sau printf("\n %f", elem->perimetru()); } //se procedeaza idem si pentru arie void afis_si_calc_perim(Patrulater *figuri_geom[]) { for(int i=0;figuri_geom[i]!=NULL;i++) { double perim; perim = figuri_geom[i]->perimetru(); cout<<"\n "<<perim; } }

int main(int argc, char **argv) { Patrulater *colectiePatrulatere[10];//vector cu 10 adrese la obiecte de tip Patrulater int i = 0; colectiePatrulatere[i++] = new Patrat(6.5); colectiePatrulatere[i++] = new Dreptunghi(6.0,7.5); colectiePatrulatere[i++] = new Patrulater(2.0,3,1,5.2); colectiePatrulatere[i++] = new Dreptunghi(2.0,1.4); colectiePatrulatere[i++] = new Dreptunghi(2.0,7.3); colectiePatrulatere[i++] = 0; //CalculeazaPerimetre(colectiePatrulatere);

//sau afis_si_calc_perim(colectiePatrulatere); int m;cin>>m; return 0; }

Desfurarea lucrrii: 1. Se ruleaz exemplele din seciunea teoretic 2. Se continu cu exemplele corespunztoare din seciunea TESTE

LABORATORUL NR.8 SUPRANCRCAREA OPERATORILOR Scop: 1. Utilizarea suprancrcarii operatorilor prin utilizarea funciilor friend 2. Utilizarea suprancrcarii operatorilor fr a utiliza funciile friend Consideraii teoretice:
Suprancrcarea operatorilor (overloading-ul) presupune redefinirea operatorilor cu ajutorul funciei de tipul operator. Restricii privind suprancrcarea operatorilor: - nu pot fi suprancrcai dect operatorii existeni; - operatorii: " . "," .* "," :: " , " ?: " i " sizeof " nu pot fi suprancrcai; - operatorii binari vor fi suprancrcai doar ca operatori binari; - operatorii unari vor fi suprancrcai doar ca operatori unari; - se pstreaz precedena operatorilor operator (nu exista posibilitatea de a determina, de exemplu, ca "+" sa fie prioritar fata de "/"); Nu este posibila definirea unui operator care sa ia ca parametri exclusiv pointeri (exceptand operatorii: = & ,). - Nu se poate modifica numarul operanzilor preluati de un operator (dar se poate ignora unul din parametri). - Un operator trebuie ori sa fie membru al unei clase, ori sa aiba cel putin un parametru de tip clasa. De la aceasta regula fac exceptie doar operatorii new si delete; - pentru operatorii : " = "," [] ", " () "," -> " funcia operator trebuie s fie membr nestatic a clasei. a)Pentru operatorul binar "op" avem: ( op poate fi unul din operatorii din lista cu operatori C++) Funcia Sintaxa formei de apel externe Sintaxa formei interne (canonice) de apel membr a clasei obiect1 op obiect2 obiect1.operator op (obiect 2) nemembr obiect1 op obiect2 operator op (obiect1, obiect2) b)Pentru operatorul unar "op" avem: Funcia Sintaxa formei de apel externe op obiect1 membr a clasei obiect1 op op obiect1 nemembr obiect1 op Sintaxa formei interne (canonice) de apel obiect1.operator op () obiect1.operator op () operator op (obiect1) operator op (obiect1)

#include <stdio.h> #include <iostream> //supaincarcarea operatorilor class VECT { double v[3]; public: //constructor declarat i explicitat n interiorul declaraiei clasei VECT()

{ v[0]=0; v[1]=0; v[2]=0;} ~VECT(){}//desctructor //declaraie constructor cu 3 argumente VECT(double x1,double x2,double x3); //VECT(VECT&);//constructor de copiere //operatorul atribuire VECT operator=(VECT); //ADUNAREA C=A+B friend VECT operator+(VECT,VECT); //C=operator+(A,B); --- C=A+B VECT operator^(VECT); //C=B.operator^(A); --- C=B+A ( B --- this)

//ADUNAREA A+=B VECT operator +=(VECT); //void operator *=(VECT); friend VECT operator ^=(VECT&,VECT&); //friend void operator |=(VECT&,VECT&); //X=-X VECT operator-(); //sau friend VECT operator!(VECT); //double& operator[](int); //friend bool operator==(VECT,VECT); void afiseaza(); }; // explicitare constructor VECT::VECT(double x,double y, double z) { v[0]=x;v[1]=y;v[2]=z; } //explicitare constructor copiere //VECT::VECT(VECT &w) //{ v[0]=w.v[0]; v[1]=w.v[1]; v[2]=w.v[2];} void VECT::afiseaza() { printf("\n Valorile: v[0]=%f,\n v[1]=%f,\n v[2]=%f",v[0],v[1],v[2]); } //operatoru de atribuire X = Y VECT VECT::operator=(VECT w) { v[0]=w.v[0];v[1]=w.v[1];v[2]=w.v[2]; return *this; } // X = W1 + W2 , operator + este funcie extern clasei VECT operator+(VECT w1,VECT w2) { VECT elem; elem.v[0]=w1.v[0]+w2.v[0]; elem.v[1]=w1.v[1]+w2.v[1]; elem.v[2]=w1.v[2]+ w2.v[2]; return elem; } // X = W1 ^ W2 , operator ^ este membr a clasei i o vom utiliza, DE //EXEMPLU pentru efectuarea ADUNAREA (adica de fapt X=W1+W2)

//unde W1 este obiectul curent (*this) VECT VECT::operator^(VECT w) // w=W2 { VECT elem; elem.v[0]=v[0] + w.v[0]; elem.v[1]=v[1] + w.v[1]; elem.v[2]=v[2] + w.v[2]; return elem; } //X+=Y VECT VECT::operator+=(VECT w) { v[0]=v[0] + w.v[0]; v[1]=v[1] + w.v[1]; v[2]=v[2] + w.v[2]; return *this; } /* void VECT::operator*=(VECT w) { v[0]=v[0] + w.v[0]; v[1]=v[1] + w.v[1]; v[2]=v[2] + w.v[2]; }*/ VECT operator^=(VECT &w1, VECT& w2) { w1.v[0]=w1.v[0]+w2.v[0]; w1.v[1]=w1.v[1]+w2.v[1]; w1.v[2]=w1.v[2]+ w2.v[2]; return w1; } /* void operator|=(VECT &w1, VECT& w2) { w1.v[0]=w1.v[0]+w2.v[0]; w1.v[1]=w1.v[1]+w2.v[1]; w1.v[2]=w1.v[2]+ w2.v[2]; }*/

// X = -X VECT VECT:: operator-() { VECT elem(-v[0],-v[1],-v[2]); return elem; } VECT operator!(VECT u) { VECT elem(-u.v[0],-u.v[1],-u.v[2]); return elem; } int main(int argc, char **argv) { //vf. atribuire /* VECT x(1,2,3),y;

y=x; y.afiseaza(); */ //vf adunare + si atribuire // VECT x(1,2,3),y(10,11,12),z; // z=x+y; //sau // z=operator+(x,y); // z.afiseaza(); //vf. adunare ^ si atribuire VECT x(100,200,300),y(10,11,12),z; //z=x^y; //sau //z=x.operator ^(y); //z.afiseaza(); //vf operator unar // /*VECT s(3,-6,9); s=-s; s.afiseaza();int m; std::cin>>m; return 0; */ /*VECT s(3,-6,9); s=!s; s.afiseaza(); int m; std::cin>>m; return 0; VECT x(1,2,3),y(10,11,12); //x^=y; //x|=y; x+=y; x.afiseaza(); // y.afiseaza(); int m; std::cin>>m;return 0; } Exemplu: #include <stdio.h> #include <iostream>

*/

//supaincarcarea operatorilor class VECT { double v[3]; public: //constructor declarat i explicitat n interiorul declaraiei clasei VECT() { v[0]=0; v[1]=0; v[2]=0;} ~VECT(){}//desctructor //declaraie constructor cu 3 argumente VECT(double x1,double x2,double x3); //VECT(VECT&);//constructor de copiere //operatorul atribuire VECT operator=(VECT); //operator indexare double& operator[](int); //supraincarcarea operatorului "identic"

friend bool operator==(VECT,VECT); bool operator<(VECT);//semnificatie schimbata in identic bool operator<=(VECT&);//semnificatie schimbata in identic void afiseaza(); }; // explicitare constructor VECT::VECT(double x,double y, double z) { v[0]=x;v[1]=y;v[2]=z; } //explicitare constructor copiere //VECT::VECT(VECT &w) //{ v[0]=w.v[0]; v[1]=w.v[1]; v[2]=w.v[2];} void VECT::afiseaza() { printf("\n Valorile: v[0]=%f,\n v[1]=%f,\n v[2]=%f",v[0],v[1],v[2]); } //operatoru de atribuire X = Y VECT VECT::operator=(VECT w) { v[0]=w.v[0];v[1]=w.v[1];v[2]=w.v[2]; return *this; } bool VECT::operator<(VECT A) { if(v[0]==A.v[0] && v[1]==A.v[1] && v[2]==A.v[2]) //this.v[0] este echivalent cu v[0] return true; return false; } bool VECT::operator<=(VECT& A) { if(v[0]==A.v[0] && v[1]==A.v[1] && v[2]==A.v[2]) return true; return false; }

bool operator==(VECT A, VECT B) {if(A.v[0]==B.v[0] && A.v[1]==B.v[1] && A.v[2]==B.v[2]) return true; return false; } double& VECT::operator[](int i) { return v[i]; }

int main(int argc, char **argv) { VECT x(10,11,12),y(10,11,12); // x.afiseaza(); bool b; // b=operator==(x,y); // b=x==y;

// b=x.operator<(y); // b=x<y; //semnificate de identitate (==) b=x<=y; //semnificate de identitate (==) if(b) printf("identice"); else printf("diferite"); /* double s; s=x[0]; printf("x[0]:%f",s); */ int m; std::cin>>m;return 0; }

Exemplu: #include <stdio.h> #include <string.h> #include <iostream>

//supaincarcarea operatorilor class VECT { double v[3]; public: //constructor declarat i explicitat n interiorul declaraiei clasei VECT() { v[0]=0; v[1]=0; v[2]=0;} ~VECT(){}//desctructor //declaraie constructor cu 3 argumente VECT(double x1,double x2,double x3); //VECT(VECT&);//constructor de copiere //operatorul atribuire VECT operator=(VECT); //operator indexare char* operator[](int); void afiseaza(); }; // explicitare constructor VECT::VECT(double x,double y, double z) { v[0]=x;v[1]=y;v[2]=z; } //explicitare constructor copiere //VECT::VECT(VECT &w) //{ v[0]=w.v[0]; v[1]=w.v[1]; v[2]=w.v[2];} void VECT::afiseaza() { printf("\n Valorile: v[0]=%f,\n v[1]=%f,\n v[2]=%f",v[0],v[1],v[2]); } //operatorul de atribuire X = Y VECT VECT::operator=(VECT w) { v[0]=w.v[0];v[1]=w.v[1];v[2]=w.v[2]; return *this; } char* VECT::operator[](int i) {char* den;

den=new char[10]; switch(i) { case 1: strcpy(den,"luni");break; case 2: strcpy(den, "marti");break; case 4: strcpy(den,"joi");break; default: strcpy(den,"zi inc."); } return den; }

int main(int argc, char **argv) { VECT x(10,11,12),y(10,11,12); // x.afiseaza(); bool b; char *zi; zi=x[10]; printf("Denumirea:1:%s",zi); int m; std::cin>>m;return 0; }

Desfurarea lucrrii: 1. Se ruleaz exemplele din seciunea teoretic 2. Se continu cu exemplele corespunztoare din seciunea TESTE

LABORATORUL NR.9 FLUXURI DE INTRARE/IEIRE. OBIECTE STANDARD

Scop: 1. nelegerea noiunii de flux I/O 2. Utilizarea obiectelor standard din cadrul claselor I/O Consideraii teoretice:
Stream-urile au in principal rolul de a abstractiza operatiile de intrare- iesire. Ele ofera metode de scriere si citire a datelor independente de dispozitivul I/O si chiar independente de platforma. Stream-urile incapsuleaza (ascund) problemele specifice dispozitivului cu care se lucreaza, sub libraria standard iostream. In C++ stream-urile au fost implementate utilizand clase, dupa cum urmeaza: clasa streambuf gestioneaza buffer-ele. clasa ios este clasa de baza pentru clasele de stream-uri de intrare si de iesire. Clasa ios are ca variabila membru un obiect de tip streambuf. clasele istream si ostream sunt derivate din ios clasa iostream este derivata din istream si ostream si ofera metode pentru lucrul cu dispozitivul standard de intrare/iesire . clasa fstream ofera metode pentru operatii cu fisiere. Obiecte standard Cand un program C++ care include iostream.h este lansat in executie, sunt create si initializate automat patru obiecte:

cin gestioneaza intrarea de la intrarea standard (tastatura). cout gestioneaza iesirea catre iesirea standard (ecranul). cerr gestioneaza iesirea catre dispozitivul standard de eroare (ecranul), neutilizand buffer-e.

Exemplu: #include <stdio.h> #include <iostream> #include <iomanip> using namespace std; class A{ static int d; int m; double t; public:

A(){m=11; } void afis() { //umple spatiul liber pana la dimensiunea data de setw(dim) cu caracterul specificat cout<<setfill('*')<<"m="<<setw(6)<<setfill('*')<<m<<";"<<endl; cout<<"d="<<setw(7)<<setfill('_')<<d<<endl; cout<<"m[hexa]="<<hex<<m<<endl; t=5.1234567; cout.precision(12); cout<<"t1="<<t<<endl; cout.precision(4); cout<<"t2="<<t<<endl; cout.precision(2); cout<<"t3="<<t<<endl; cout<<setprecision(5)<<"t4="<<t<<endl;

} }; int A::d=8; //se declara ca variabila globala int main(int argc, char **argv) { A x; x.afis(); //std::cout<<"TEST"; //int m; std::cin>>m; // pe post de asteapta o tasta }

Desfurarea lucrrii: 1. Se ruleaz exemplele din seciunea teoretic 2. Se continu cu exemplele corespunztoare din seciunea TESTE

LABORATORUL NR.10 FLUXURI DE INTRARE/IEIRE. OPERATII DE INTRARE/IESIRE CU FISIERE Scop: Realizarea operaiilor cu fiiere utiliznd fluxurile I/O Consideraii teoretice:
Lucrul cu fisiere se face prin intermediul clasei ifstream pentru citire respectiv ofstream pentru scriere. Pentru a le utiliza, aplicatiile trebuie sa includa fstream.h. Clasele ofstream si ifstream sunt derivate din clasa iostream, ca urmare toti operatorii si toate functiile descrise mai sus sunt mostenite si de aceasta clasa.
Exemplu: #include #include #include #include <stdio.h> <iostream> <iomanip> <fstream>

using namespace std; // FISIERE TEXT class A{ public: int scrie_in_Fisier(char* numefis) { ofstream fis1(numefis); //deschidere fiier text.txt //ofstream fis1(numefis,ios::app|ios::out); //adauga, la sfarsit, fara trunchiere fisier if (!fis1){ cout<<"Eroare la dechiderea fiierului!\n"; return 1;} fis1<<"A111 B222 "; fis1<<"ABCD "; fis1<<15<<" "<<13; fis1.close(); } int citeste_din_Fisier(char* numefis) { char a[3][100]; int b[3]; ifstream fis2(numefis); //deschiderea fis. ptr. citire if (!fis2){cout<<"Eroare la deschiderea fis. ptr. citire!\n";return 1;} fis2>>a[0]>>a[1]>>a[2]>>b[0]>>b[1]; cout<<"a[0]:"<<a[0]<<" a[1]:"<<a[1]<<" a[2]:"<<a[2]<<" b[0]:"<<b[0]<<" b[1]:"<<b[1]<<endl; fis2.close(); } };

int main(int argc, char **argv) { A x; x.scrie_in_Fisier("test24.txt");

x.citeste_din_Fisier("test24.txt"); return 0; }

Desfurarea lucrrii: 1. Se ruleaz exemplele din seciunea teoretic 2. Se continu cu exemplele corespunztoare din seciunea TESTE

LABORATORUL NR.11 TRATAREA EXCEPIILOR Scop: Implementarea metodelor de control a posibilelor erori din cadrul unei aplicaii Consideraii teoretice:
n timpul executrii unui program pot aprea situaii n care sunt generate erori datorate de multe ori depirii puterii de reprezentare a numerelor, de operaii nepermise, de contori n afara limitelor admise, etc. Ca urmare este necesar anticiparea unor posibile excepii, de multe ori provenite de la preluarea incorect a datelor. C + + ofer trei cuvinte cheie pentru a gestiona o excepie: try , catch i throw. Cuvntul cheie try este urmat de blocul ce se execut i care poate genera o eroare n execuie try { bloc ce se execut n mod normal} Acest cuvnt cheie permite aplicaiei s anticipeze un comportament anormal i va ncerca s se ocupe de ea. catch { bloc ce se execut n cazul n care apare o excepie/eroare } Acest cuvnt cheie este urmat, ntre acolade, de blocul ce se execut n cazul unei excepii/erori throw transmite excepia, n vederea tratrii acesteia, ctre sistemul de operare.
Ex: #include <iostream> using namespace std; int main() { int a,b,c; cout << "a= "; cin >> a; cout << "b= ";cin >> b; try { if( b==0 ) throw; c = a / b;

} catch() { cout<<b este zero; } cout << "\n"; return 0; }

Cele trei puncte din argumentul catch semnific faptul c vor fi tratate toate excepiile. Pentru particularizarea tratrii erorii, putem proceda ca n exemplul urmtor:
#include <iostream.h> int main()

int a,b,c; cout << "a= "; cin >> a; try { cout << "b= "; cin >> b; if(b == 0) throw "b este ZERO !"; c = a / b;

} catch(const char* Message) { cout << "Error: " << Message; } cout << "\n"; return 0; }

n cazul n care sunt tratate mai multe excepii putem avea:


try { // codul ce poate contine exceptii/erori } catch(Arg1) { //tratarea primei excetii } catch(Arg2) { //tratarea urmatoarei exceptii }

Deosebirea ntre argumente se va face prin tipurile acestora Ex:


#include <iostream.h> int main() { int a,b,c; cout << "a= "; cin >> a; try { cout << "b= "; cin >> b; if(b == 0) throw "b este ZERO !"; if(b == 1) throw 1; if(b == 2) throw '2'; c=a/b+a/(b-1)+a/(b-2); catch(const char* Message) { cout << "Error: b=0; } catch(const int Message) { cout << "Error:b=1; } catch(const char Message) { cout << "Error: b=2"; } cout << "\n"; return 0;

Desfurarea lucrrii: 1. Se ruleaz exemplele din seciunea teoretic 2. Se continu cu exemplele corespunztoare din seciunea TESTE

LABORATORUL NR.12 UTILIZAREA CLASELOR WXWIDGETS (I) Scop: Familiarizarea cu uneltele de dezvoltare a interfeelor grafice Consideraii teoretice: Clasele wxWidgets se constituie ntr-un se de instrumente C++ ce permit crearea de interfae grafice GUI (Graphical User Interface) n C++. Aceste clase sunt open source i cross-platform. aplicaiile wxWidgets pot rula pe toate sub toate sistemele de operare reprezentative: Linux, Windows, Unix si Mac. Proiectul a fost demarat de ctre Julian inteligente n 1992. Clasa wxString este utilizat pentru lucrul cu irurile de caractere.
#include <wx/string.h> int main(int argc, char **argv) { wxString str1 = wxT("Un"); wxString str2 = wxT("prim"); wxString str3 = wxT("exemplu."); wxString str = str1 + wxT(" ") + str2 + wxT(" ") + str3; wxPuts(str); }

Formatarea irurilor
#include <wx/string.h> int main(int argc, char **argv) { int a = 10; wxString str; str.Printf(wxT("a= %d\n",a); wxPuts(str); wxPrintf(wxT("irul are lungimea de %d caractere.\n"), str.Len()); }

Clasa wxFile este utilizat pentru lucrul cu fiiere


#include <wx/file.h> int main(int argc, char **argv) { wxString str = wxT("Un sir de caractere.\n"); wxFile file; file.Create(wxT("numefisier"), true); if (file.IsOpened()) wxPuts(wxT("Fisierul este deschis")); file.Write(str); file.Close(); if (!file.IsOpened()) wxPuts(wxT("Fisierul NU este deschis")); }

Desfurarea lucrrii: 1. Se ruleaz exemplele din seciunea teoretic 2. Se continu cu exemplele corespunztoare din seciunea TESTE

LABORATORUL NR.13 UTILIZAREA CLASELOR WXWIDGETS (II) Scop: Familiarizarea cu uneltele de dezvoltare a interfeelor grafice Consideraii teoretice:
n vederea realizrii interfeelor grafice este necesar utilizarea metodelor (din cadrul claselor date) ce asigur gestiunea evenimentelor la nivel de aplicaie. Ex:Realizarea unui mic formular utiliznd wxFormBuilder gui.h --wxWidgets license (www.wxwidgets.org) -- fiier generat de wxFormBuilder - necesar negerii structurii claselor
#ifndef __gui__ #define __gui__ #include <wx/intl.h> #include <wx/statline.h> #include <wx/gdicmn.h> #include <wx/font.h> #include <wx/colour.h> #include <wx/settings.h> #include <wx/string.h> #include <wx/sizer.h> #include <wx/button.h> #include <wx/dialog.h> // Class MainDialogBase class MainDialogBase : public wxDialog { private: protected: wxStaticLine* m_staticLine; wxStdDialogButtonSizer* m_sdbSizer; wxButton* m_sdbSizerOK; wxButton* m_sdbSizerCancel; virtual void OnCloseDialog( wxCloseEvent& event ) { event.Skip(); } virtual void OnCancelClick( wxCommandEvent& event ) { event.Skip(); } virtual void OnOKClick( wxCommandEvent& event ) { event.Skip(); } public: MainDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("wxMiniApp"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 400,300 ), long style = wxCLOSE_BOX|wxDEFAULT_DIALOG_STYLE ); ~MainDialogBase(); }; #endif //__gui__

gui.cpp - wxWidgets license (www.wxwidgets.org) -- fiier generat de wxFormBuilder - necesar negerii structurii claselor
#include "gui.h" MainDialogBase::MainDialogBase( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) { this->SetSizeHints( wxSize( -1,-1 ), wxDefaultSize ); wxBoxSizer* mainSizer; mainSizer = new wxBoxSizer( wxVERTICAL ); mainSizer->Add( 0, 0, 1, wxEXPAND, 5 ); m_staticLine = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); mainSizer->Add( m_staticLine, 0, wxEXPAND | wxALL, 5 ); m_sdbSizer = new wxStdDialogButtonSizer(); m_sdbSizerOK = new wxButton( this, wxID_OK ); m_sdbSizer->AddButton( m_sdbSizerOK ); m_sdbSizerCancel = new wxButton( this, wxID_CANCEL ); m_sdbSizer->AddButton( m_sdbSizerCancel ); m_sdbSizer->Realize(); mainSizer->Add( m_sdbSizer, 0, wxALIGN_RIGHT|wxBOTTOM|wxRIGHT, 5 ); this->SetSizer( mainSizer ); this->Layout(); this->Centre( wxBOTH ); // conectarea handler-ului de evenimentelor this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( MainDialogBase::OnCloseDialog ) ); m_sdbSizerCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogBase::OnCancelClick ), NULL, this ); m_sdbSizerOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogBase::OnOKClick ), NULL, this ); } MainDialogBase::~MainDialogBase() {// Eliberarea handler-ului de evenimente this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( MainDialogBase::OnCloseDialog ) ); m_sdbSizerCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogBase::OnCancelClick ), NULL, this ); m_sdbSizerOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogBase::OnOKClick ), NULL, this ); }

main.h
#ifndef __main__ #define __main__ // main wxWidgets header file #include <wx/wx.h> // gui classes generated by wxFormBuilder #include "gui.h" class MainApp : public wxApp { public: virtual bool OnInit(); }; DECLARE_APP(MainApp) class MainDialog : public MainDialogBase { public: MainDialog( wxWindow *parent );

virtual ~MainDialog(); protected: virtual void OnCloseDialog( wxCloseEvent& event ); virtual void OnOKClick( wxCommandEvent& event ); virtual void OnCancelClick( wxCommandEvent& event ); }; #endif //__main__

main.cpp
#include "main.h" IMPLEMENT_APP(MainApp); bool MainApp::OnInit() { SetTopWindow( new MainDialog( NULL ) ); GetTopWindow()->Show(); return true; } MainDialog::MainDialog(wxWindow *parent) : MainDialogBase( parent ) { } MainDialog::~MainDialog() { } void MainDialog::OnCloseDialog(wxCloseEvent& event) { Destroy(); } void MainDialog::OnOKClick(wxCommandEvent& event) { Destroy(); } void MainDialog::OnCancelClick(wxCommandEvent& event) { } Destroy();

Desfurarea lucrrii: 1. Se lanseaz wxFormBuilder i se construiete interfaa 2. Se lanseaz CodeLite i se adaug metodele ce reprezint rspunsul la evenimente 3. Se compileaz i link-editeaz

LABORATORUL NR.14 TESTE Scop: Testarea cunotinelor TEST#1 Se dau urmtoarele clase:
#include <iostream> #include <stdio.h> #include <string.h> class A1 {int x1; protected:char *numevar; protected: int s1,y1; public: int t1; A1() {numevar=new char[100];strcpy(numevar,"N/A"); afis("CONSTRUCTOR_0"); } A1(char *numevar1) {numevar=new char[100]; strcpy(numevar,numevar1); afis("CONSTRUCTOR1"); } A1(char *numevar1,int x11, int y11) {numevar=new char[100]; strcpy(numevar,numevar1); afis("CONSTRUCTOR2"); } ~A1() {afis("DESTRUCTOR");delete[] numevar;} virtual void afis(char *str); private: void calc(); }; void A1::afis(char *str) {std::cout<<"A1#numevar:"<<numevar<<"-"<<str<< std::endl;} class B2: public A1 { int x2,y2,x1,y1,s1,t1; protected: int s2,t2; public: B2():A1() {afis("CONSTRUCTOR_0"); } B2(char *numevar1):A1(numevar1) {afis("CONSTRUCTOR_1"); } B2(char *numevar1,int x11,int y11,int s22): A1(numevar1,x11,y11) { s2=s22;afis("CONSTRUCTOR_2"); } ~B2() {afis("DESTRUCTOR");} void afis(char *str); }; void B2::afis(char *str) {std::cout<<"B2#numevar:"<<numevar<<"-"<<str<< std::endl;} void C3::afis(char *str) {std::cout<<"C3#numevar:"<<numevar<<"-"<<str<< std::endl;} //1. Ce se afieaz n urma execuiei ? int main(int argc, char* argv[]) {C3 a1[3], *b2; {A1 c3("c3"),*d4[2],e5("e5",5,4); {B2 f6("f6");} C3 g7("g7"); B2 *h8=new B2("s5",21,17,19);delete h8; b2=new C3("b2",101,32,54); } delete b2; getchar(); return 0; } 2. Modificai clasa A1 astfel nct la fiecare apel al vreunui constructor sau al destructorului s afieze numrul total al obiectelor instaniate. Adugai codul necesar i n afara clasei. 3.Se d: int main(int argc, char* argv[]) { A1 w2("d1",5,4),*d[3],e[3]; B2 g2("g2",21,17,19); C3 m2("m2",101,32,54); // d[0]=&w2; d[1]=&g2; d[2]=&m2; // e[0]=w2; e[1]=g2; e[2]=m2; // d[0]->afis("d[0]"); d[1]->afis("d[1]"); d[2]->afis("d[2]"); // return 0; } 3.1. Este posiblil asignarea d[0]=&w2? Dar invers (w2=*d[0])? Explicai! 3.2. Este posiblil asignarea d[1]=&g2? Dar invers (g2=*d[1])? Explicai! 3.3. Este posiblil asignarea d[2]=&m2? Dar invers (m2=*d[2])? Explicai!

class C3: protected A1 3.4. Este posiblil asignarea e[0]=w2;? Dar { int x3,y3; protected: int s3,t3; invers? Explicai! public: C3():A1() {afis("CONSTRUCTOR_0"); } C3(char *numevar1):A1(numevar1) 3.5. Este posiblil asignarea e[1]=g2;? Dar {afis("CONSTRUCTOR_1"); } invers?Explicai! C3(char *numevar1,int x11,int y11,int s33): A1(numevar1,x11,y1 3.6. Este posiblil asignarea e[2]=m2;? Dar 1) {s3=s33;afis("CONSTRUCTOR_2"); } invers?Explicai! ~C3() {afis("DESTRUCTOR");} void afis(char *str); 4. Se d o clas ce conine coordonatele x,y ale };

unui 4.1. dou 4.2.

punct ntr-un plan. S se suprancarce: conine coordonatele punctului Un operator pentru calculul distanei dintredistanei dintre cele dou puncte. puncte. Un operator ce ntoarce un nou obiect ce

la

jumtatea

TEST #2
Se dau urmtoarele clase: #include <iostream> #include <stdio.h> #include <string.h> class A1 {int x1; protected:char *numevar; protected: int s1,y1; public: int t1; A1() {numevar=new char[100];strcpy(numevar,"N/A"); afis("CONSTRUCTOR_0"); } A1(char *numevar1) {numevar=new char[100]; strcpy(numevar,numevar1); afis("CONSTRUCTOR1"); } A1(char *numevar1,int x11, int y11) {numevar=new char[100]; strcpy(numevar,numevar1); afis("CONSTRUCTOR2"); } ~A1() {afis("DESTRUCTOR");delete[] numevar;} virtual void afis(char *str); private: void calc(); }; void A1::afis(char *str) {std::cout<<"A1#numevar:"<<numevar<<"-"<<str<< std::endl;} class B2: public A1 { int x2,y2,x1,y1,s1,t1; protected: int s2,t2; public: B2():A1() {afis("CONSTRUCTOR_0"); } B2(char *numevar1):A1(numevar1) {afis("CONSTRUCTOR_1"); } B2(char *numevar1,int x11,int y11,int s22): A1(numevar1,x11,y11) { s2=s22;afis("CONSTRUCTOR_2"); } ~B2() {afis("DESTRUCTOR");} void afis(char *str); }; void B2::afis(char *str) {std::cout<<"B2#numevar:"<<numevar<<"-"<<str<< std::endl;} //1. Ce se afieaz n urma execuiei ? int main(int argc, char* argv[]) {B2 a1("a1"),b2[2]; {A1 c3,d4("d4",5,4); {C3 f5("f5"); B2 *g6=new C3("g6",21,17,19);delete g6; } } getchar(); return 0; } 2. Modificai clasele astfel nct s contorizeze numrul obiectelor ce au utilizat la instaniere constructori cu un singur parametru. Adugai codul necesar i n afara clasei. 3.Se d: int main(int argc, char* argv[]) { A1 w2("d1",5,4),*d[3],e[3]; B2 g2("g2",21,17,19); C3 m2("m2",101,32,54); // d[0]=&w2; d[1]=&g2; d[2]=&m2; // e[0]=w2; e[1]=g2; e[2]=m2; // d[0]->afis("d[0]"); d[1]->afis("d[1]"); d[2]->afis("d[2]"); // return 0; } 3.1. Este posiblil asignarea d[0]=&w2? Dar invers (w2=*d[0])? Explicai! 3.2. Este posiblil asignarea d[1]=&g2? Dar invers (g2=*d[1])? Explicai! 3.3. Este posiblil asignarea d[2]=&m2? Dar invers (m2=*d[2])? Explicai! 3.4. Este posiblil asignarea e[0]=w2;? Dar invers? Explicai! 3.5. Este posiblil asignarea e[1]=g2;? Dar invers?Explicai! 3.6. Este posiblil asignarea e[2]=m2;? Dar invers?Explicai!

4. Se d o clas ce conine coordonatele x,y ale vrfurilor unui dreptunghi. class C3: protected A1 S se suprancarce: { int x3,y3; protected: int s3,t3; 4.1. Un operator pentru calculul ariei de public: intersecie a dou obiecte. C3():A1() {afis("CONSTRUCTOR_0"); } 4.2. Un operator ce ntoarce un nou obiect ce C3(char *numevar1):A1(numevar1) conine vrfurile drepunghiului rezultat n urma {afis("CONSTRUCTOR_1"); } interseciei a dou obiecte. C3(char *numevar1,int x11,int y11,int s33): A1(numevar1,x11,y1 1) {s3=s33;afis("CONSTRUCTOR_2"); } ~C3() {afis("DESTRUCTOR");} void afis(char *str); }; void C3::afis(char *str) {std::cout<<"C3#numevar:"<<numevar<<"-"<<str<< std::endl;}

TEST #3 Se dau urmtoarele clase:


#include <iostring> #include <stdio.h> #include <string.h> class A1 {int x1; char *numevar; protected: int s1,y1; public: int t1; A1() {numevar=new char[100];strcpy(numevar,"N/A"); afis("CONSTRUCTOR_0");} A1(char *numevar1) {numevar=new char[100]; strcpy(numevar,numevar1); afis("CONSTRUCTOR1");} A1(char *numevar1,int x11, int y11) {numevar=new char[100]; strcpy(numevar,numevar1); afis("CONSTRUCTOR2");} ~A1() {afis("DESTRUCTOR");delete[] numevar;} virtual void afis(char *str); private: void calc(); }; void A1::afis(char *str) {std::cout<<"A1#numevar:"<<numevar<<"-"<<str<< std::endl;} class B2: public A1 { char *numevar; int x2,y2,x1,y1,s1,t1; protected: int s2,t2; public: B2(char *numevar1):A1(numevar1) {numevar=new char[100]; strcpy(numevar,numevar1); afis("CONSTRUCTOR1"); } B2(char *numevar1,int x11,int y11,int s22): A1(numevar1,x11,y11) { numevar=new char[100]; strcpy(numevar,numevar1); s2=s22;afis("CONSTRUCTOR2"); } ~B2() {afis("DESTRUCTOR");delete[] numevar;} void afis(char *str); }; void B2::afis(char *str) {std::cout<<"B2#numevar:"<<numevar<<"-"<<str<< std::endl;} strcpy(numevar,numevar1); s3=s33;afis("CONSTRUCTOR_2"); } ~C3() {afis("DESTRUCTOR");delete[] numevar;} void afis(char *str); }; void C3::afis(char *str) {std::cout<<"C3#numevar:"<<numevar<<"-"<<str<< std::endl;} 1. Ce se afieaz n urma execuiei ? int main(int argc, char* argv[]) {C3 *t01; {A1 y1("y1"),d2[2],r3("r3",5,4); B2 g4("g4"),*s5; C3 q6("q6"); s5=new B2("s5",21,17,19); t01=new C3("t01",101,32,54); delete s5; } delete t01; getchar(); return 0; }

R
2. Adugai cte un contor pentru numrul de obiecte instaniate, pentru fiecare clas n parte (adugai direct pe codul scris i rescriei numai metodele modificate). Afiai acest numr n cadrul constructorilor i destructorilor.

3.Se d: int main(int argc, char* argv[]) { A1 w2("d1",5,4),d[3]; B2 g2("g2",21,17,19); C3 m2("m2",101,32,54); d[0]=w2; d[1]=g2;// 4.1 d[2]=m2; //4.2 d[0].afis("d[0]");//4.3 d[1].afis("d[1]");//4.3 d[2].afis("d[2]");//4.3 getch(); return 0; } 3.1. Este posiblil asignarea d[1]=g2;? Explicai!

3.2. Este posiblil asignarea d[2]=m2;? class C3: protected A1 Explicai! { char *numevar; int x3,y3; protected: int s3,t3; 3.3. n cazul n care este posibil asignarea ce public: se afieaz n urma apelului metodei C3(char *numevar1):A1(numevar1) afis(d[i]) , i=0,1 sau 2 ? Explicai! {numevar=new char[100]; strcpy(numevar,numevar1); afis("CONSTRUCTOR_1"); 4. Sa se scrie o clasa ce contine un operator } suprancarcat pentru operatia de concatenarea a C3(char *numevar1,int x11,int y11,int s33): doi vectori cu numere de tip double si un A1(numevar1,x11,y1 operator supaincarcat pentru operatia de ordonare 1) crescatoare a elementelor vectorului. {numevar=new char[100];

TEST #4 Se dau urmtoarele clase:


#include <iostream> #include <stdio.h> #include <string.h> //1. Ce se afieaz n urma execuiei ?

int main(int argc, char* argv[]) {C3 *a1, b2[2]; {A1 c3("c3"),*d4[2],e5("e5",5,4); {B2 f6("f6");} class A1 C3 g7("g7"); {int x1; protected:char *numevar; B2 *h8=new B2("s5",21,17,19);delete h8; protected: int s1,y1; b2=new C3("b2",101,32,54); public: int t1; } A1() delete b2; {numevar=new char[100];strcpy(numevar,"N/A"); getchar(); afis("CONSTRUCTOR_0"); return 0; } } A1(char *numevar1) R {numevar=new char[100]; strcpy(numevar,numevar1); 2. Modificai clasa A1 astfel nct la fiecare afis("CONSTRUCTOR1"); apel al vreunui constructor sau al destructorului } s afieze numrul total al obiectelor A1(char *numevar1,int x11, int y11) instaniate. Adugai codul necesar i n afara {numevar=new char[100]; clasei. strcpy(numevar,numevar1); afis("CONSTRUCTOR2"); } 3.Se d: ~A1() {afis("DESTRUCTOR");delete[] numevar;} int main(int argc, char* argv[]) virtual void afis(char *str); { private: A1 w2("d1",5,4),*d[3],e[3]; void calc(); B2 g2("g2",21,17,19); }; C3 m2("m2",101,32,54); //........................... void A1::afis(char *str) d[0]=&w2; d[1]=&g2; d[2]=&m2; {std::cout<<"A1#numevar:"<<numevar<<"-"<<str<< //.......................... std::endl;} e[0]=w2; e[1]=g2; e[2]=m2; //........................... class B2: protected A1 d[0]->afis("d[0]"); { int x2,y2,x1,y1,s1,t1; d[1]->afis("d[1]"); d[2]->afis("d[2]"); protected: int s2,t2; //.................................... public: return 0; B2():A1() } {afis("CONSTRUCTOR_0"); } B2(char *numevar1):A1(numevar1) 3.1. Este posiblil asignarea d[0]=&w2? Dar {afis("CONSTRUCTOR_1"); } invers (w2=*d[0])? Explicai! B2(char *numevar1,int x11,int y11,int s22): A1(numevar1,x11,y11) { s2=s22;afis("CONSTRUCTOR_2"); } 3.2. Este posiblil asignarea d[1]=&g2? Dar ~B2() {afis("DESTRUCTOR");} invers (g2=*d[1])? Explicai! void afis(char *str); }; 3.3. Este posiblil asignarea d[2]=&m2? Dar invers (m2=*d[2])? Explicai! void B2::afis(char *str) {std::cout<<"B2#numevar:"<<numevar<<"-"<<str<< std::endl;} 3.4. Este posiblil asignarea e[0]=w2;? Dar invers? Explicai! class C3: public A1 { int x3,y3; protected: int s3,t3; public: 3.5. Este posiblil asignarea e[1]=g2;? Dar invers?Explicai! C3():A1() {afis("CONSTRUCTOR_0"); } C3(char *numevar1):A1(numevar1) {afis("CONSTRUCTOR_1"); } 3.6. Este posiblil asignarea e[2]=m2;? Dar C3(char *numevar1,int x11,int y11,int s33): invers?Explicai! A1(numevar1,x11,y1 . 1) {s3=s33;afis("CONSTRUCTOR_2"); } 4. Se d o clas ce conine coordonatele x,y ale ~C3() {afis("DESTRUCTOR");} unui punct ntr-un plan. S se suprancarce: void afis(char *str); 4.1. Un operator pentru calculul distanei dintre }; dou puncte. 4.2. Un operator ce ntoarce un nou obiect ce void C3::afis(char *str) conine coordonatele punctului la jumtatea {std::cout<<"C3#numevar:"<<numevar<<"-"<<str<< distanei dintre cele dou puncte. std::endl;}

TEST #5 Se dau urmtoarele clase:


#include <iostream> #include <stdio.h> #include <string.h> class A1 {int x1; protected:char *numevar; protected: int s1,y1; public: int t1; A1() {numevar=new char[100];strcpy(numevar,"N/A"); afis("CONSTRUCTOR_0"); } A1(char *numevar1) {numevar=new char[100]; strcpy(numevar,numevar1); afis("CONSTRUCTOR1"); } A1(char *numevar1,int x11, int y11) {numevar=new char[100]; strcpy(numevar,numevar1); afis("CONSTRUCTOR2"); } ~A1() {afis("DESTRUCTOR");delete[] numevar;} virtual void afis(char *str); private: void calc(); }; void A1::afis(char *str) {std::cout<<"A1#numevar:"<<numevar<<"-"<<str<< std::endl;} class B2: protected A1 { int x2,y2,x1,y1,s1,t1; protected: int s2,t2; public: B2():A1() {afis("CONSTRUCTOR_0"); } B2(char *numevar1):A1(numevar1) {afis("CONSTRUCTOR_1"); } B2(char *numevar1,int x11,int y11,int s22): A1(numevar1,x11,y11) { s2=s22;afis("CONSTRUCTOR_2"); } ~B2() {afis("DESTRUCTOR");} void afis(char *str); }; void B2::afis(char *str) {std::cout<<"B2#numevar:"<<numevar<<"-"<<str<< std::endl;} ~C3() {afis("DESTRUCTOR");} void afis(char *str); }; void C3::afis(char *str) {std::cout<<"C3#numevar:"<<numevar<<"-"<<str<< std::endl;} //1. Ce se afieaz n urma execuiei:

int main(int argc, char* argv[]) {A1 a1,*b2;*c3[3]; {B2 d4("d4,2,4); {C3 e5("e5");} B2 *b2=new B2("s5",21,17,19); } } delete b2; getchar(); return 0; }

int main(int argc, char* argv[]) { A1 w2("d1",5,4),e[3]; B2 g2("g2",21,17,19); C3 m2("m2",101,32,54); return 0; } 2.1.Explicai dac sunt sa nu posibile urmroarele asignri: 1. e[0].s1=5;.............................. R: ................................... 2.w2.t1=9; .............................. R: ................................... 3.w2.t1=e[0].s1; ......................... R: ................................... 4.g2.t1=9; .............................. R: ................................... 5.g2.t1=g2.t2; ............................ R: ................................... 6.m2.x3=g2.x2; .............................. R: ................................... 7.m2.s3=9; .............................. R: ................................... 8.m2.s1=9; .............................. R: ................................... 9.m2.x1=9; .............................. R: ................................... 10.m2.t3=g2.t2; .............................. R: ...................................

3. Se d o clas ce gestioneaz elementele unui class C3: public A1 ir de caractere (aceast clas va conine un { int x3,y3; public: int s3,t3; pointer la un ir de numere de tip real). public: S se suprancarce un operator care s permit C3():A1() {afis("CONSTRUCTOR_0"); } obinerea unui obiect avnd irul de numere C3(char *numevar1):A1(numevar1) {afis("CONSTRUCTOR_1"); } ordonat cresctor (se va scrie declaraia clasei, C3(char *numevar1,int x11,int y11,int s33): explicitarea unui constructor, explicitarea A1(numevar1,x11,y1 1) destructorului i explicitarea funciei operator). {s3=s33;afis("CONSTRUCTOR_2"); }

TEST #6 Se dau urmtoarele clase:


#include #include #include #include <conio.h> <iostream.h> <iomanip.h> <string.h> {B2 g2("g2"),*g1;; {A1 d1[2],w2("d1",15,41); C3 m1("m1"); } g1=new B2("g1",51,29); delete g1; } getch(); return 0; }

class A1 {int g; protected: int h; public:int xa,ya;char numevar[20]; static int s; A1() {xa=0;ya=0;strcpy(numevar,N/A); afis("CONSTRUCTOR_0); } A1(char*); A1(char*, int); A1(char*,int,int); ~A1() {afis("DESTRUCTOR");} virtual void afis(char *str); virtual void tipar(); }; A1::A1(char *numevar1) {xa=0;ya=0;strcpy(numevar,numevar1); afis("CONSTRUCTOR_1"); } A1::A1(char *numevar1, int x1) {xa=x1;ya=0;;strcpy(numevar,numevar1); afis("CONSTRUCTOR_2"); } A1::A1(char *numevar1,int x1, int y1) {xa=x1;ya=y1;;strcpy(numevar,numevar1); afis("CONSTRUCTOR_3"); } void A1::afis(char *str) {cout<<A1_var:<<numevar<< tip:<<str<<endl;} class B2: protected A1 { public:int xb,yb; B2(char *numevar1):A1(numevar1) {xb=0; yb=0; afis("CONSTRUCTOR_1");} B2(char *numevar1,int x1,int m1): A1(numevar1,x1) { xb=m1;yb=0;afis("CONSTRUCTOR_3"); ~B2() {afis("DESTRUCTOR");} void afis(char *str); void tipar(); };

2.Este posibil execuia urmtoarelor instruciuni? Explicai de ce!


2.1. void main() {A1 d1[2]; d1[0].g=1;} 2.2. void main() {B2 d1[2]; d1[1].g=3;} 2.3. void main() {B2 d1[2]; d1[1].xa=7;}

...

2.4. void main() {B2 d1[2]; d1[1].h=5;}

.....
2.5. void main() {C3 a; a.h=7;}

........

2.6. void main() {C3 a; a.g=9;}

......................
2.7. void main() {C3 a; a.xa=1;}

. .

2.8. void main() {A1 *m[2]; C3 a; m[0]=@a;} 2.9. void main() {A1 m[2]; C3 *a; a=m[0];}

...........

2.10. void main() {A1 m[2]; C3 *a; a>xa=(int)&m[0];}

. 3. Ce se afieaz n urma execuiei ?


}

void B2::afis(char *str) {cout<<B2_var:<<numevar<< tip:<<str<<endl;}

void A1::tipar() {cout<<xa=<<setw(7)<<setfill('^')<<hex<<xa<<en dl;} void B2::tipar() {cout<<setw(7)<<setfill('~')<<xb=<<hex<<xb<<en dl;} void C3::tipar() {cout<<xc=<<setw(7)<<setfill('#')<<hex<<xc<<en dl;}

iar class C3:public A1 in loc de class C3:private A1 i class B2:public A1 n loc de class B2:protected A1 class C3: private A1 { public:int xc,yc; void main() C3():A1(){xc=0;yc=0;afis("CONSTRUCTOR_0);} {A1 *m[3],r1("var-r1",45); B2 r2("var-r2",46,47); C3(char *numevar1):A1(numevar1) C3 r3("var-r3",48,49,43,44); {xc=0;yc=0; afis("CONSTRUCTOR_1"); m[0]=&r1;m[1]=&r2; m[2]=&r3; } m[0]->tipar(); C3(char *numevar1,int x1,int y1,int s1, int m[1]->tipar(); t1): A1(numevar1,x1,y1) m[2]->tipar(); getch();} {xc=s1;yc=t1;afis("CONSTRUCTOR_5"); } ~C3() {afis("DESTRUCTOR");} 4. Se d o clas pentru gestiunea operaiilor cu void afis(char *str); void tipar(); date calendaristice. Clasa conine o variabil ce }; void C3::afis(char *str) {cout<<C3_var:<<numevar<< tip:<<str<<endl;}

1. Ce se afieaz n urma execuiei ?


int main() {C3 *m2;

memoreaz numrul se minute raportat la 31.12,1899, ora 24:00:00.000. S se suprancarce un operator care s permit adunare cu un anumit numr de ore (se va scrie declaraia clasei, explicitarea unui constructor i explicitarea funciei operator).

TEST #7 Se dau urmtoarele clase:


#include #include #include #include <conio.h> <iostream.h> <iomanip.h> <string.h> } delete r1; getch(); return 0;

class A1 {int g; protected: int h; public:int xa,ya;char numevar[20]; static: int 2.1. void main() {A1 d1[2]; d1[0].g=1;} s; A1() {xa=0;ya=0;strcpy(numevar,N/A);afis("CONSTR UCTOR_0);} 2.2. void main() {B2 d1[2]; d1[1].g=3;} A1(char *numevar1) {xa=0;ya=0;strcpy(numevar,numevar1);afis("CON 2.3. void main() {B2 d1[2]; d1[1].xa=7;} STRUCTOR_1");} ................................. A1(char *numevar1, int x1) {xa=x1;ya=0;;strcpy(numevar,numevar1);afis("C 2.4. void main() {B2 d1[2]; d1[1].h=5;} ONSTRUCTOR_2");} A1(char *numevar1,int x1, int y1) {xa=x1;ya=y1;;strcpy(numevar,numevar1);afis(" 2.5. void main() {C3 a; a.h=7;} ................................ CONSTRUCTOR_3");} ~A1() {afis("DESTRUCTOR");} 2.6. void main() {C3 a; a.g=9;} virtual void afis(char *str); ................................ virtual void tipar(); 2.7. void main() {C3 a; a.xa=1;} }; void A1::afis(char *str) {cout<<A1_var:<<numevar<< tip:<<str<<endl;} class B2: public A1 { public:int xb,yb; B2(char *numevar1):A1(numevar1) {xb=0; yb=0; afis("CONSTRUCTOR_1");} B2(char *numevar1,int x1,int m1): A1(numevar1,x1) { xb=m1;yb=0;afis("CONSTRUCTOR_3"); ~B2() {afis("DESTRUCTOR");} void afis(char *str); void tipar(); };

R: 2.Este posibil execuia urmtoarelor instruciuni? Explicai de ce!

................................
2.8. void main() {A1 *m[2]; C3 a; m[0]=@a;} 2.9. void main() {A1 m[2]; C3 *a; a=m[0];}

.............................. ..............................
2.10. void main() {A1 m[2]; C3 *a; a>xa=(int)&m[0];}

.............................. 3. Ce se afieaz n urma execuiei ?

void B2::afis(char *str) {cout<<B2_var:<<numevar<< tip:<<str<<endl;}

class C3: protected A1 { public:int xc,yc; C3():A1(){xc=0;yc=0;afis("CONSTRUCTOR_0);} iar class C3:public A1 in loc de class C3:protected A1 C3(char *numevar1):A1(numevar1) {xc=0;yc=0; afis("CONSTRUCTOR_1"); void main() } {A1 *m[3],r1("var-r1",15); B2 r2("var-r2",2,3); C3(char *numevar1,int x1,int y1,int s1, int C3 r3("var-r3",4,5,6,7); t1): m[0]=&r3;m[1]=&r2; m[2]=&r1; A1(numevar1,x1,y1) m[0]->tipar(); {xc=s1;yc=t1;afis("CONSTRUCTOR_5"); m[1]->tipar(); } m[2]->tipar(); ~C3() {afis("DESTRUCTOR");} getch();} void afis(char *str); void tipar(); }; 4. Se d o clas ce gestioneaz elementele unui ir void C3::afis(char *str) {cout<<C3_var:<<numevar<< tip:<<str<<e;}

void A1::tipar() {cout<<xa=<<setw(7)<<setfill('*')<<hex<<xa<<en dl;} void B2::tipar() {cout<<setw(7)<<setfill('*')<<xb=<<hex<<xb<<en dl;} void C3::tipar() {cout<<xc=<<setw(7)<<setfill('*')<<hex<<xc<<en dl;}

1. Ce se afieaz n urma execuiei ?


int main() { A1 *r1; {A1 w2("d1",13,12),d1[2]; C3 m1("m1"); r1=new A1("r1",11,61); B2 g2("g2"); }

de caractere (aceast clas va conine un pointer la un ir de caractere). S se suprancarce un operator care s permit adugarea unui caracter la sfrsitul irului (se va scrie declaraia clasei, explicitarea unui constructor, explicitarea destructorului i explicitarea funciei operator).

TEST #8 Se dau urmtoarele clase:


#include #include #include #include <conio.h> <iostream.h> <iomanip.h> <string.h> B2 *g1; {A1 w1("d1"); g1=new B2("g1",21,19); } {C3 m1("m1"); r1=new A1("r1",11,61); delete g1; } delete r1; getch(); return 0; }

class A1 {int g; protected: int h; public:int xa,ya;char numevar[20]; static int s; A1() {xa=0;ya=0;strcpy(numevar,N/A); afis("CONSTRUCTOR_0); } A1(char*); A1(char*, int); A1(char*,int,int); ~A1() {afis("DESTRUCTOR");} virtual void afis(char *str); virtual void tipar(); }; A1::A1(char *numevar1) {xa=0;ya=0;strcpy(numevar,numevar1); afis("CONSTRUCTOR_1"); } A1::A1(char *numevar1, int x1) {xa=x1;ya=0;;strcpy(numevar,numevar1); afis("CONSTRUCTOR_2"); } A1::A1(char *numevar1,int x1, int y1) {xa=x1;ya=y1;;strcpy(numevar,numevar1); afis("CONSTRUCTOR_3"); } void A1::afis(char *str) {cout<<A1_var:<<numevar<< tip:<<str<<endl;} class B2: protected A1 { public:int xb,yb; B2(char *numevar1):A1(numevar1) {xb=0; yb=0; afis("CONSTRUCTOR_1");} B2(char *numevar1,int x1,int m1): A1(numevar1,x1) { xb=m1;yb=0;afis("CONSTRUCTOR_3"); ~B2() {afis("DESTRUCTOR");} void afis(char *str); void tipar(); };

2.Este posibil execuia urmtoarelor instruciuni? Explicai de ce!


2.1. 2.2. 2.3. 2.4. 2.5. void void void void void main() main() main() main() main() {A1 {B2 {B2 {B2 {C3 d1[2]; d1[0].g=1;} d1[2]; d1[1].g=3;} d1[2]; d1[1].xa=7;} d1[2]; d1[1].h=5;} a; a.h=7;}

.......................
2.6. void main() {C3 a; a.g=9;}

..................... ..

2.7. void main() {C3 a; a.xa=1;} 2.8. void main() {A1 *m[2]; C3 a; m[0]=@a;}

..................

2.9. void main() {A1 m[2]; C3 *a; a=m[0];}

.......................
2.10. void main() {A1 m[2]; C3 *a; a>xa=(int)&m[0];}

3. Ce se afieaz n urma execuiei ?


void A1::tipar() {cout<<xa=<<setw(7)<<setfill('^')<<hex<<xa<<en dl;} void B2::tipar() {cout<<setw(7)<<setfill('~')<<xb=<<hex<<xb<<en dl;} void C3::tipar() {cout<<xc=<<setw(7)<<setfill('#')<<hex<<xc<<en dl;} iar class C3:public A1 in loc de class C3:private A1 i class B2:public A1 n loc de class B2:protected A1 void main() {A1 *m[3],r1("var-r1",51); B2 r2("var-r2",52,53); C3 r3("var-r3",54,55,56,57); m[0]=&r1;m[1]=&r2; m[2]=&r3; m[0]->tipar(); m[1]->tipar(); m[2]->tipar(); getch();}

void B2::afis(char *str) {cout<<B2_var:<<numevar<< tip:<<str<<endl;} class C3: private A1 { public:int xc,yc; C3():A1(){xc=0;yc=0;afis("CONSTRUCTOR_0);} C3(char *numevar1):A1(numevar1) {xc=0;yc=0; afis("CONSTRUCTOR_1"); } C3(char *numevar1,int x1,int y1,int s1, int t1): A1(numevar1,x1,y1) {xc=s1;yc=t1;afis("CONSTRUCTOR_5"); } ~C3() {afis("DESTRUCTOR");} void afis(char *str); void tipar(); }; void C3::afis(char *str) {cout<<C3_var:<<numevar<< tip:<<str<<endl;}

1. Ce se afieaz n urma execuiei ?


int main() {A1 d1[2],*r1;

4. Se d o clas pentru gestiunea operaiilor cu date calendaristice. Clasa conine o variabil ce memoreaz numrul se minute raportat la 31.12.1899, ora 24:00:00.000. S se suprancarce un operator care s permit adunare cu un anumit numr de zile (se va scrie declaraia clasei, explicitarea unui constructor i explicitarea funciei operator).

TEST #9 Se dau urmtoarele clase:


#include #include #include #include <conio.h> <iostream.h> <iomanip.h> <string.h> {cout<<C3_var:<<numevar<< tip:<<str<<endl;}

1. Ce se afieaz n urma execuiei ?


int main() { C3 m1("m1"); B2 *g1,g2("g2",1,4); {A1 d1[2]; {A1 w2("w2",5,4); g1=new B2("g1",21,17); } delete g1; } getch(); return 0; }

class A1 {int g; protected: int h; public:int xa,ya;char numevar[20]; static int s; A1() {xa=0;ya=0;strcpy(numevar,N/A); afis("CONSTRUCTOR_0); } A1(char*); A1(char*, int); A1(char*,int,int); ~A1() {afis("DESTRUCTOR");} virtual void afis(char *str); virtual void tipar(); }; A1::A1(char *numevar1) {xa=0;ya=0;strcpy(numevar,numevar1); afis("CONSTRUCTOR_1"); } A1::A1(char *numevar1, int x1) {xa=x1;ya=0;;strcpy(numevar,numevar1); afis("CONSTRUCTOR_2"); } A1::A1(char *numevar1,int x1, int y1) {xa=x1;ya=y1;;strcpy(numevar,numevar1); afis("CONSTRUCTOR_3"); } void A1::afis(char *str) {cout<<A1_var:<<numevar<< tip:<<str<<endl;} class B2: protected A1 { public:int xb,yb; B2(char *numevar1):A1(numevar1) {xb=0; yb=0; afis("CONSTRUCTOR_1");} B2(char *numevar1,int x1,int m1): A1(numevar1,x1) { xb=m1;yb=0;afis("CONSTRUCTOR_3"); ~B2() {afis("DESTRUCTOR");} void afis(char *str); void tipar(); };

. 2.Este posibil execuia urmtoarelor instruciuni? Explicai de ce!


22.1. void main() {A1 d1[2]; d1[0].g=1;} 2.2. void main() {B2 d1[2]; d1[1].g=3;} 2.3. void main() {B2 d1[2]; d1[1].xa=7;} 2.4. void main() {B2 d1[2]; d1[1].h=5;} 2.5. void main() {C3 a; a.h=7;} 2.6. void main() {C3 a; a.g=9;} 2.7. void main() {C3 a; a.xa=1;} 2.8. void main() {A1 *m[2]; C3 a; m[0]=@a;} 2.9. void main() {A1 m[2]; C3 *a; a=m[0];} 2.10. void main() {A1 m[2]; C3 *a; a>xa=(int)&m[0];}

. 3. Ce se afieaz n urma execuiei ?


void A1::tipar() {cout<<xa=<<setw(7)<<setfill('^')<<hex<<xa<<en dl;} void B2::tipar() {cout<<setw(7)<<setfill('~')<<xb=<<hex<<xb<<en dl;} void C3::tipar() {cout<<xc=<<setw(7)<<setfill('#')<<hex<<xc<<en dl;} iar class C3:public A1 in loc de class C3:private A1 i class B2:public A1 n loc de class B2:protected A1 void main() {A1 *m[3],r1("var-r1",31); B2 r2("var-r2",32,33); C3 r3("var-r3",34,35,36,37); m[0]=&r3;m[1]=&r2; m[2]=&r1; m[0]->tipar(); m[1]->tipar(); m[2]->tipar(); getch();}

void B2::afis(char *str) {cout<<B2_var:<<numevar<< tip:<<str<<endl;}

class C3: private A1 { public:int xc,yc; C3():A1(){xc=0;yc=0;afis("CONSTRUCTOR_0);} C3(char *numevar1):A1(numevar1) {xc=0;yc=0; afis("CONSTRUCTOR_1"); 4. Se d o clas pentru gestiunea operaiilor cu } date calendaristice. Clasa conine o variabil ce C3(char *numevar1,int x1,int y1,int s1, int t1): memoreaz numrul se minute raportat la A1(numevar1,x1,y1) 31.12.1899, ora 24:00:00.000. {xc=s1;yc=t1;afis("CONSTRUCTOR_5"); } S se suprancarce un operator care s permit ~C3() {afis("DESTRUCTOR");} adunare cu un anumit numr de secunde (se va void afis(char *str); void tipar(); scrie declaraia clasei, explicitarea unui }; void C3::afis(char *str)

constructor i explicitarea funciei operator).

TEST #10 Se dau urmtoarele clase:


#include <conio.h> #include <stdio.h> #include <string.h> C3(char *numevar1,int x11,int y11,int s33): A1(numevar1,x11,y11) {numevar=new char[100]; strcpy(numevar,numevar1); s3=s33;afis("CONSTRUCTOR2 C3"); } ~C3() {afis("DESTRUCTOR C3");delete[] numevar;} void afis(char *str); }; void C3::afis(char *str) {printf("\n %s -- numevar:%s x3=%d y3=%d s3=%d t3=%d",str,numevar,x3,y3,s3,t3);}

class A1 {int x1,y1; char *numevar; protected: int s1; public: int t1; 1. Ce se afieaz n urma execuiei ? A1() {numevar=new char[100];strcpy(numevar,"N/A"); int main(int argc, char* argv[]) x1=0;y1=0;s1=-1;t1=-1;afis("CONSTRUCTOR_0 {C3 *m2; A1 *r1; A1");} {A1 d1[2],w1("d1"),w2("d1",5,4); A1(char *numevar1) B2 *g1,g2("g2"); {numevar=new char[100]; C3 m1("m1"); strcpy(numevar,numevar1); g1=new B2("g1",21,17,19); x1=0;y1=0;s1=-1;t1=-1;afis("CONSTRUCTOR1 A1");} m2=new C3("m2",101,32,54); delete m2; A1(char *numevar1,int x11, int y11) r1=new A1("r1",11,61); {numevar=new char[100]; delete g1; strcpy(numevar,numevar1); } x1=x11; y1=y11; s1=0;t1=0;afis("CONSTRUCTOR2 delete r1; A1");} getch(); ~A1() {afis("DESTRUCTOR A1");delete[] numevar;} return 0; virtual void afis(char *str); } private: 2.1.Ce va afia funcia afis(char *str) dac nu void calc(); este apelat ultima n cadrul unui constructor? }; 2.2. Ce va afia funcia afis(char *str) dac nu este apelat prima n cadrul unui destructor? void A1::afis(char *str) {printf("\n %s -- numevar:%s x1=%d y1=%d s1=%d t1= 2.3 De ce nu a putut fi afiat numevar i pentru %d",str,numevar,x1,y1,s1,t1);} construcorul implicit? class B2: public A1 2.4 Ce legtur exist ntre variabila numevar { char *numevar; din clasa de baz i cea declarat n clasele int x2,y2,x1,y1,s1,t1; derivate? protected: 2.5.Pentru variabilele declarate la pct.1. Este int s2,t2; posibil accesul lui g1->t1? Explicai! public: Dar al lui m1->t1 ? Explicai! B2(char *numevar1):A1(numevar1) {numevar=new char[100]; 3. Adugai cte un contor pentru numrul de strcpy(numevar,numevar1); obiecte instaniate, pentru fiecare clas n parte x2=0; y2=0; s2=0; t2=0; s1=-2;t2=-2; (adugai direct pe codul scris i rescriei numai afis("CONSTRUCTOR1 B2"); metodele modificate). Afiai acest numr n } cadrul constructorilor i destructorilor. B2(char *numevar1,int x11,int y11,int s22): 4.Se d: A1(numevar1,x11,y11) int main(int argc, char* argv[]) { numevar=new char[100]; { strcpy(numevar,numevar1); A1 w2("d1",5,4),d[3]; s2=s22;afis("CONSTRUCTOR2 B2"); B2 g2("g2",21,17,19); } C3 m2("m2",101,32,54); ~B2() {afis("DESTRUCTOR B2");delete[] numevar;} d[0]=w2; void afis(char *str); d[1]=g2;// 4.1 }; d[2]=m2; //4.2 d[0].afis("d[0]");//4.3 void B2::afis(char *str) d[1].afis("d[1]");//4.3 {printf("\n %s -- numevar:%s x2=%d y2=%d s2=%d d[2].afis("d[2]");//4.3 t2=%d",str,numevar,x2,y2,s2,t2);} getch(); return 0; class C3: protected A1 } { char *numevar; int x3,y3; 4.1. Este posiblil asignarea d[1]=g2;? protected: Explicai! int s3,t3; .4.2. Este posiblil asignarea d[2]=m2;? public: C3(char *numevar1):A1(numevar1) Explicai!. {numevar=new char[100]; 4.3. n cazul n care este posibil asignarea ce strcpy(numevar,numevar1); se afieaz n urma apelului metodei x3=0;y3=0;s3=0;t3=0;s1=-3;t1=-3; afis(d[i]) , i=0,1 sau 2 ? Explicai! afis("CONSTRUCTOR1 C3"); }

BIBLIOGRAFIE

http://www.unixinside.org/papers/C++-Book/ http://codelite.org/Main/ReadMore Dan Somnea,Doru Turturea, Editura Tehnica 1993, Initiere in C++ programarea orientata pe obiecte

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