POO - C++ - indrumar laborator

49
PROGRAMAREA ORIENTATĂ PE OBIECTE ÎNDRUMAR DE LABORATOR Liviu Şerbănescu UNIVERSITATEA HYPERION

description

POO indrumar laborator ptr. C++

Transcript of POO - C++ - indrumar laborator

Page 1: POO - C++ - indrumar laborator

PROGRAMAREA ORIENTATĂ PE OBIECTE

ÎNDRUMAR DE LABORATOR

Liviu Şerbănescu UNIVERSITATEA HYPERION

Page 2: POO - C++ - indrumar laborator

LISTA LUCRĂRILOR

1. Iniţiere într-un mediu de programare. Structura unui program C++.

2. Noţiunea de clasă şi obiect. Operatori specifici C++.

3. Clase şi moşteniri. Clase de bază virtuale

4. Constructori şi destructori

5. Modificatorii şi specificatorii de acces

6. Date şi funcţii de tip friend şi statice

7. Polimorfism, funcţii virtuale

8. Supraîncărcarea operatorilor

9. Fluxuri de intrare/ieşire.Obiecte standard

10. Fluxuri de intrare/ieşire.Operatii de intrare/iesire cu fisiere

11. Tratarea excepţiilor

12. Utilizarea claselor wxWidgets (I)

13. Utilizarea claselor wxWidgets (II)

14. Teste.

Page 3: POO - C++ - indrumar laborator

LABORATORUL NR.1

INIŢIERE ÎNTR-UN MEDIU DE PROGRAMARE. STRUCTURA UNUI PROGRAM C++

Scop:

1. Familiarizarea cu mediul integrat CodeLite.

2. Înţelegerea structurii unui program scris în limbajul C++.

3. Înţelegerea bibliotecilor ce utilizează programarea orientată pe obiecte.

Consideraţii teoretice:

Mediul integrat - OpenSource - CodeLite

Un spaţiu de lucru (workspace) detine un numar de proiecte, de exemplu, acestea pot avea legătură unele cualtele sau nu Crearea unui spaţiu de lucru se realizează prin selectarea " "Workspace | Create new Workspace""Un proiect (project) poate avea va rezultat în urma compilării şi apoi a link-editării un executabil, o bibliotecă dinamică (*.DLL), o bibliotecă statică(*.LIB), etc. Proiectul în sine conţine toate informaţiile necesare pentru a produce o aplicaţie de un anumit tip (aplicaţie consolă, aplicaţie grafică ce utilizează un anumit set de controale vizuale, aplicaţie cu obiecte grafice, etc).Fişierul ce conţine informaţii despre spaţiul de lucru se numeşte <workspace-name>.workspaceFişierul ce conţine informaţii despre proiect este <project-name>. prjPentru crearea unui proiect nou se va utiliza opţiunea GUI (Graphics User Interface).

Structura unui program C++

Un programC++ cuprinde următoarele elemente pricipale:

✗ operatori (aritmetici, logici, etc)

✗ instrucţiuni (de decizie, de parcurgere a unei bucle, etc)

✗ funcţii (apelate din cadrul bibliotecilor sau definite de utilizator)

✗ variabile şi constante

✗ funcţia main()

Textul unui program poate fi scris într-un fişier sau în mai multe fişiere. Un program va avea o singură funcţie main() indiferent dacă este scris într-un singur fisier sau în mai multe fişiere. Programul compilat şi linkeditat va incepe întodeauna prin lansarea în execuţie a instrucţiunilor şi funcţiilor din cadrul lui main(). Prin ieşirea din funcţia main() se încheie şi execuţia programului.

Page 4: POO - C++ - indrumar laborator

Desfăşurarea lucrării:

1. Lansarea mediului CodeLite, şi studierea principalelor componente ale interfeţei

acestuia

2. Crearea unor spaţii de lucru

3. Crearea unui proiect pentru aplicaţie consolă

4. Compilarea unui exemplu. Modificarea setărilor implicite de compilare.

5. Executarea separată aLink-editării pentru o aplicaţie. Modificarrea setărilor

implicite pentru link-editare

6. Adăugarea bibliotecilor cu clase.

7. Recompilarea (având şi biblioteci cu clase)

8. Relinkeditarea .

Page 5: POO - C++ - indrumar laborator

LABORATORUL NR.2

NOŢIUNEA DE CLASĂ ŞI OBIECT. OPERATORI SPECIFICI C++

Scop:

1. Înţelegerea noţiunilor de clasă şi obiect

2. Înţelegerea operatorilor specifici C++

Consideraţii 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 funcţiile (membrele / metodele) unei clase

Datele sunt reprezentate prin declarațiile 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 încapsulării (ascunderea informaţiei ce stă la baza realizării 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 (atât codul cât și apelul acestora). Conform principiului încapsulării utilizatorul nu are acces la date ci numai la metodele pe care dezvoltatorul clasei le-a lăsat pentru a putea fi apelate.

Operatorii specifici C++OPERATORUL SIMBOLU

LFORMA Operaţia realizată

rezoluţie / indicator acces

:: ::a ::f()

- accesează variabilele globale chiar dacă au acelaşi nume cu cele locale

- accesează membrii/membrele claselorvaloare .* OB.*a - întoarce valoarea (OB valoare)

valoare ->* OB->*a - întoarce valoarea (OB pointer)

new new new tipalocă memorie. ex ptr. un vector de 10 întregi:

new int[10], întoarce NULL în caz de eşec altfel întoarce adresa alocată

delete deletedelete adelete a[]

eliberează zona de memorie

this this this/ *thisarată adresa obiectului curent (în care ne aflăm) iar *this este valoarea obiectului

curent

Desfăşurarea lucrării:

1. Se execută exemplele corespunzătoare din secţiunea TESTE

Page 6: POO - C++ - indrumar laborator

LABORATORUL NR.3

CLASE ŞI MOŞTENIRI. CLASE DE BAZĂ VIRTUALE

Scop:

1. Înţegerea moştenirii claselor

2. Utilizarea funcţiilor şi a claselor de bază virtuale

Consideraţii teoretice:

Procedeul de derivare permite definirea unei clase noi, numită clasă derivată, care moşteneşte propietăţile (membri + membre) unei clase deja definite, numită clasă de bază, pe care le completează cu propietăţi (membri+membre) noi. Clasa de bază nu este afectată şi nu trebuie recompilată, declaraţia (fişierul header) şi codul obiect (fişier 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 "părinte" (bază) şi le adaugă un anumit grad de specializare. În cazul în care o clasă moşteneşte proprietăţile mai multor clase avem moştenire multiplă. Sintaxa declaraţia 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ă (moştenire multiplă): class nume_clasa_derivata : modificator_acces nume_clasă_baza_1 [<, modificator_acces nume_clasă_baza_n >]

Funcţiile constructor, destructor şi mecanismul de moştenireClasa de bază, clasa derivată, sau ambele, pot avea funcţii constructor şi/sau destructor. Când o clasă de bază şi una derivată conţin atât funcţii constructor cât şi destructor, cele constructor sunt executate în ordinea derivării iar funcţiile destructor sunt executate în ordine inversă. Adică duncţia 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ă. Când se explicitează costructorul din clasa derivată trebuie să se specifice care din constructorii clasei de bază este apelat ( constructorii diferă între ei - în momentul declarării - prin numărul ş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_clasa_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 moştenirii 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ă virtualePresupunem ca avem o clasă BAZA şi două clase ce derivă din BAZA, numite DER1 şi DER2. Apoi din DER1 şi DER2 derivăm o altă clasă denumită DER12 . Deci, clasa DER12 moşteneşte de două ori clasa BAZA, o dată prin DER1 şi o dată prin DER2. Acest lucru determină o ambiguitate când clasa DER12 vrea să aibă acces la datele din clasa BAZA. (de ex. pot fi date din clasa BAZA, modificate în cadrul clasei DER1

Page 7: POO - C++ - indrumar laborator

sau modificate în cadrul clasei DER2 - atât DER1 cât şi DER2 au câte 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ă cuvântul 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

Desfăşurarea lucrării:

1. Se rulează exemplele din secţiunea teoretică

2. Se continuă cu exemplele corespunzătoare din secţiunea TESTE

Page 8: POO - C++ - indrumar laborator

LABORATORUL NR.4

CONSTRUCTORI ŞI DESTRUCTORI

Scop:

1. Utilizarea constructorilor

2. Utilizarea destructorilor

3. Înţegerea ordinii de apel a constructorilor

4. Înţelegerea ordinii de apel a destructorilor

Consideraţii teoretice:

CONSTRUCTORI: Constructorul se apelează automat la crearea fiecărui obiect al clasei, creare de tip static,

automatic sau dinamic; Funcţia constructor are acelaşi nume cu al clasei (case sensitive); O clasă poate avea mai mulţi constructuri, ei se deosebesc prin numărul şi tipul argumentelor; In cazul în care nu se scrie nici un constructor se va apela automat un constructor, fără

argumente şi de tip public. Dacă utilizatorul declară cel puţin un constructor atunci compilatorul nu mai generează acest constructor implicit;

Există şi un constructor implicit de copiere ce iniţializează obiectul curent cu datele (membrii) din alt obiect de acelaşi tip (aparţinând aceleiaşi clase) El are forma nume_clasă(nume_clasa &)şi poate fi redefinit;

Constructorii nu întorc valori; Constructorii sunt apelaţi automat după ce se se alocă memorie (automatic sau static) pentru

obiectele membru (date membru /membrii)

DESTRUCTORI: Destructorul este apelat automat când obiectul respectiv îşi încetează existenţa în memorie. Destructorul are acelaşi 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 apelaţi automat înaintea eliberării memoriei alocată automatic sau static pentru

datele membru.

Explicitarea funcţiilor membre (inclusiv a constructorilor şi destructorilor) se poate face fie în interiorul declaraţiei clasei, fie în exteriorul clasei prin utilizarea operatorului rezoluţie " :: ".Funcţiile din cadrul unei clase se pot clasifica în: - constructori; - destructori; - funcţii normale de acces; - funcţii de tip prieten (friend); - funcţii virtuale; - funcţii statice;

Page 9: POO - C++ - indrumar laborator

- funcţii 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;

Page 10: POO - C++ - indrumar laborator

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++) 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;

} }while(!ordonat); }

Page 11: POO - C++ - indrumar laborator

/*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;}

Desfăşurarea lucrării:

1. Se rulează exemplul din secţiunea teoretică

2. Se continuă cu exemplele corespunzătoare din secţiunea TESTE

Page 12: POO - C++ - indrumar laborator

LABORATORUL NR.5

MODIFICATORII ŞI SPECIFICATORII DE ACCES

Scop:

1. Înţelegerea noţiunilor de privite, protected şi public

2. Utilizarea modificatorilor de acces în cadrul constructorilor

3. Utilizarea specificatorilor de acces.

4. Înţelegerea drepturilor de acces în condiţiile în care avem atât modificatori de acces cât

şi specificatori de acces

Consideraţii teoretice

Datele (membrii) şi membrele (funcţiile) din interiorul unei clase pot avea următorii 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 văzute decât în interiorul clasei.Implicit toate datele şi metodele din cadrul unei clase sunt private.Daca constructorii nu ar fi declaraţi cu specificatorul de acces public nu am putea avea obiecte de tipul clasei respective în afara clasei.

Modificatorii de accesSpecificatorul de acces din clasa de

bază

Modificator de acces

Accesul moştenit de clasa derivată

Accesul din exterior

privateprotected

public

privateprivateprivate

inaccesibilprivateprivate

inaccesibilinaccesibilinaccesibil

privateprotected

public

publicpublicpublic

inaccesibilprotected

public

inaccesibilinaccesibilaccesibil

Exemplu

//main.h

class P_ABC

{ protected:

char *sir_c,tip;

long *sir_l;

double *sir_d;

short dim;

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

~P_ABC();

virtual void afisare()=0;

Page 13: POO - C++ - indrumar laborator

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);

};

Page 14: POO - C++ - indrumar laborator

//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;}

Page 15: POO - C++ - indrumar laborator

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;}

Desfăşurarea lucrării:

1. Se rulează exemplele din secţiunea teoretică

2. Se continuă cu exemplele corespunzătoare din secţiunea TESTE

Page 16: POO - C++ - indrumar laborator

LABORATORUL NR.6

DATE ŞI FUNCŢII DE TIP FRIEND ŞI STATICE

Scop:

1. Înţelegerea tipului de dată friend pentru o clasă

2. Înţelegerea tipului de dată static pentru membrii unei clase

3. Utilizarea instanţierii claselor cu metode statice

Consideraţii teoretice:

Funcţii de tipul "prieten" (friend)O funcţie de tip friend (prieten) este o funcţie care nu este membră a clasei şi are acces la toţi membrii clasei. În interiorul clasei, ea se declară prin scrierea cuvântului cheie friend înaintea declararaţiei propiu-zise a funcţiei. O clasă ale cărei funcţii sunt, în totalitate, friend pentru altă clasă se numesţe clasă prietenă a acelei clase.O funcţie prieten, este o funcţie declarată în afara clasei (nu aparţine clasei) şi căreia i se dă acces la toate datele din cadrul clasei. În interiorul clasei este declarată cu cuvântul 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"Cuvântul cheie this arată adresa obiectului curent (în care ne aflăm) iar *this este valoarea obiectului curent.

Page 17: POO - C++ - indrumar laborator

//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 existenteclass 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 instantiateint 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;

}

Desfăşurarea lucrării:

1. Se rulează exemplele din secţiunea teoretică

2. Se continuă cu exemplele corespunzătoare din secţiunea TESTE

Page 18: POO - C++ - indrumar laborator

LABORATORUL NR.7

POLIMORFISM, FUNCŢII VIRTUALE

Scop:

1. Înţelegerea noţiunii de polimorfism

2. Utilizarea funcşiilor virtuale

Consideraţii teoretice:

Funcţiile virtuale sunt folosite pentru implementarea obiectelor polimorfice. Obiectele polimorfice se careacterizează prin faptul că folosind aceeaşi formă de apel pentru funcţiile membre realizăm operaţii diferite. Funcţiile viruale implementează filozofia "o singură interfaţă, mai multe metode", care pune în evidenţă "poli morfism-ul"

Variabile de tip pointer care punctează la clasele derivatePresupunem două clase, denumite:BAZA şi DERIVATA, unde clasa DERIVATA moşteneşte clasa BAZA. În aceste condiţii, următoarele instrucţiuni sunt valabile:BAZA *p; // pointer-ul care punctează la clasa bazaBAZA OB_TIP_BAZA; //un obiect de tip BAZADERIVATA OB_TIP_DER; // un obiect de tip DERIVATA// pointer-ul p poate puncta (prelua adresa) la obiecte de tip BAZAp=&OB_TIP_BAZA; // p preia adresa lui OB_TIP_BAZA// p poate puncta la obiecte derivatep=&OB_TIP_DER; // p preia adresa lui OB_TIP_DERUn pointer al clasei de bază poate puncta la un obiect din clasa derivată, fără a genera vreo eroare, invers nu este valabil. Prin acest pointer putem avea acces doar la membrii clasei derivate care au fost moşteniţi de la clasa de bază.

Funcţii virtualeO funcţie virtuală este o funcţie membră a unei clase, care se declară în interiorul unei clase de bază şi se redefineşte (modifică) în clasele derivate. Pentru a crea o funcţie virtuală, trebuie să utilizăm cuvântul cheie virtual, înainte de declaraţia funcţiei. La nivelul fiecărei clase funcţiile virtuale împlementează cod specific clasei respective, însă ele au acelaşi nume, aceeaşi listă de parametrii şi întorc aceelaşi tip de dată. Când un pointer al clasei de bază punctează la o funcţie virtuală din clasa derivată, şi aceasta este apelată prin intermediul acestui pointer, compilatorul determină care versiune (care din codurile/ care explicitare) a funcţiei trebuie apelată, ţinând cont de tipul obiectului (care clasă) la care punctează acel pointer. Adică tipul obiectului (clasa ) la care punctează determină versiunea funcţiei virtuale care va fi executată.O funcţie virtuală poate fi declarată şi numai formal, ea nerealizând nimic concret, ea fiind declarată doar pentru ca în clasele derivate să fie declarată şi explicitată. O astfel de funcţie virtuală, fără cod/explicitare se numeşte funcţie virtuală pură. Sintaxa pentru o funcţie virtuală pură este: virtual tip nume_funcţie(listă_de_parametri)=0;O clasă ce conţine o funcţie virtuală pură se numeşte clasă abstractă. Clasele abstracte sunt utilizate doar pentru a fi moştenite. Nu se pot intanţia obiecte pentru clase abstracte.

//polimorfism

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

Page 19: POO - C++ - indrumar laborator

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;

}

Page 20: POO - C++ - indrumar laborator

Desfăşurarea lucrării:

1. Se rulează exemplele din secţiunea teoretică

2. Se continuă cu exemplele corespunzătoare din secţiunea TESTE

Page 21: POO - C++ - indrumar laborator

LABORATORUL NR.8

SUPRAÎNCĂRCAREA OPERATORILOR

Scop:

1. Utilizarea supraîncărcarii operatorilor prin utilizarea funcţiilor friend

2. Utilizarea supraîncărcarii operatorilor fără a utiliza funcţiile friend

Consideraţii teoretice:

Supraîncărcarea operatorilor (overloading-ul) presupune redefinirea operatorilor cu ajutorul funcţiei de tipul operator.Restricţii privind supraîncărcarea operatorilor:- nu pot fi supraîncărcaţi decât operatorii existenţi;- operatorii: " . "," .* "," :: " , " ?: " şi " sizeof " nu pot fi supraîncărcaţi;- operatorii binari vor fi supraîncărcaţi doar ca operatori binari;- operatorii unari vor fi supraîncărcaţi doar ca operatori unari;- se păstrează precedenţa 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 : " = "," [] ", " () "," -> " funcţia 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++)

Funcţia Sintaxa formei de apel externe Sintaxa formei interne (canonice) de apelmembră a clasei obiect1 op obiect2 obiect1.operator op (obiect 2)

nemembră obiect1 op obiect2 operator op (obiect1, obiect2)

b)Pentru operatorul unar "op" avem:Funcţia Sintaxa formei de apel externe Sintaxa formei interne (canonice) de apel

membră a claseiop obiect1obiect1 op

obiect1.operator op ()obiect1.operator op ()

nemembrăop obiect1obiect1 op

operator op (obiect1)operator op (obiect1)

#include <stdio.h>#include <iostream>

//supaincarcarea operatorilorclass VECT {double v[3];public://constructor declarat şi explicitat în interiorul declaraţiei claseiVECT(){ v[0]=0; v[1]=0; v[2]=0;}

Page 22: POO - C++ - indrumar laborator

~VECT(){}//desctructor//declaraţie constructor cu 3 argumenteVECT(double x1,double x2,double x3);//VECT(VECT&);//constructor de copiere//operatorul atribuireVECT operator=(VECT);

//ADUNAREA C=A+B friend VECT operator+(VECT,VECT); //C=operator+(A,B); --- C=A+BVECT operator^(VECT); //C=B.operator^(A); --- C=B+A ( B --- this)

//ADUNAREA A+=BVECT operator +=(VECT);//void operator *=(VECT);friend VECT operator ^=(VECT&,VECT&);//friend void operator |=(VECT&,VECT&);

//X=-XVECT operator-();//saufriend VECT operator!(VECT);

//double& operator[](int);//friend bool operator==(VECT,VECT);void afiseaza();};

// explicitare constructorVECT::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 = YVECT 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 funcţie externă claseiVECT 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];

Page 23: POO - C++ - indrumar laborator

elem.v[2]=v[2] + w.v[2];return elem;}

//X+=YVECT 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 = -XVECT 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

Page 24: POO - C++ - indrumar laborator

// 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 operatorilorclass VECT {double v[3];public://constructor declarat şi explicitat în interiorul declaraţiei claseiVECT(){ v[0]=0; v[1]=0; v[2]=0;}~VECT(){}//desctructor//declaraţie constructor cu 3 argumenteVECT(double x1,double x2,double x3);//VECT(VECT&);//constructor de copiere//operatorul atribuireVECT operator=(VECT);//operator indexaredouble& operator[](int);//supraincarcarea operatorului "identic"friend bool operator==(VECT,VECT);bool operator<(VECT);//semnificatie schimbata in identicbool operator<=(VECT&);//semnificatie schimbata in identicvoid afiseaza();};

// explicitare constructorVECT::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]);}

Page 25: POO - C++ - indrumar laborator

//operatoru de atribuire X = YVECT 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 operatorilorclass VECT {

Page 26: POO - C++ - indrumar laborator

double v[3];public://constructor declarat şi explicitat în interiorul declaraţiei claseiVECT(){ v[0]=0; v[1]=0; v[2]=0;}~VECT(){}//desctructor//declaraţie constructor cu 3 argumenteVECT(double x1,double x2,double x3);//VECT(VECT&);//constructor de copiere//operatorul atribuireVECT operator=(VECT);//operator indexarechar* operator[](int);void afiseaza();};

// explicitare constructorVECT::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 = YVECT 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;

}

Desfăşurarea lucrării:

Page 27: POO - C++ - indrumar laborator

1. Se rulează exemplele din secţiunea teoretică

2. Se continuă cu exemplele corespunzătoare din secţiunea TESTE

Page 28: POO - C++ - indrumar laborator

LABORATORUL NR.9

FLUXURI DE INTRARE/IEŞIRE.OBIECTE STANDARD

Scop:

1. Înţelegerea noţiunii de flux I/O

2. Utilizarea obiectelor standard din cadrul claselor I/O

Consideraţii 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()

Page 29: POO - C++ - indrumar laborator

{ //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

}

Desfăşurarea lucrării:

1. Se rulează exemplele din secţiunea teoretică

2. Se continuă cu exemplele corespunzătoare din secţiunea TESTE

Page 30: POO - C++ - indrumar laborator

LABORATORUL NR.10

FLUXURI DE INTRARE/IEŞIRE.OPERATII DE INTRARE/IESIRE CU FISIERE

Scop:

Realizarea operaţiilor cu fişiere utilizând fluxurile I/O

Consideraţii 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 <stdio.h>#include <iostream>#include <iomanip>#include <fstream>

using namespace std;// FISIERE TEXTclass A{public:int scrie_in_Fisier(char* numefis) { ofstream fis1(numefis); //deschidere fişier text.txt //ofstream fis1(numefis,ios::app|ios::out); //adauga, la sfarsit, fara trunchiere fisier if (!fis1){ cout<<"Eroare la dechiderea fişierului!\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;

Page 31: POO - C++ - indrumar laborator

}

Desfăşurarea lucrării:

1. Se rulează exemplele din secţiunea teoretică

2. Se continuă cu exemplele corespunzătoare din secţiunea TESTE

Page 32: POO - C++ - indrumar laborator

LABORATORUL NR.11

TRATAREA EXCEPŢIILOR

Scop:

Implementarea metodelor de control a posibilelor erori din cadrul unei aplicaţii

Consideraţii teoretice:

În timpul executării unui program pot apărea situaţii în care sunt generate erori datorate de multe ori depăşirii puterii de reprezentare a numerelor, de operaţii nepermise, de contori în afara limitelor admise, etc. Ca urmare este necesară anticiparea unor posibile excepţii, de multe ori provenite de la preluarea incorectă a datelor. C + + oferă trei cuvinte cheie pentru a gestiona o excepţie:try , catch şi throw.

Cuvântul cheie try este urmat de blocul ce se execută şi care poate genera o eroare în execuţietry { bloc ce se execută în mod normal}Acest cuvânt cheie permite aplicaţiei să anticipeze un comportament anormal şi va încerca să se ocupe de ea.

catch { bloc ce se execută în cazul în care apare o excepţie/eroare }Acest cuvânt cheie este urmat, între acolade, de blocul ce se execută în cazul unei excepţii/erori

throw transmite excepţia, în vederea tratării acesteia, către 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 excepţiile.

Pentru particularizarea tratării erorii, putem proceda ca în exemplul următor:

#include <iostream.h>

int main()

Page 33: POO - C++ - indrumar laborator

{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 excepţii 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;

}

Desfăşurarea lucrării:

1. Se rulează exemplele din secţiunea teoretică

2. Se continuă cu exemplele corespunzătoare din secţiunea TESTE

Page 34: POO - C++ - indrumar laborator

LABORATORUL NR.12

UTILIZAREA CLASELOR WXWIDGETS (I)

Scop: Familiarizarea cu uneltele de dezvoltare a interfeţelor grafice

Consideraţii teoretice:

Clasele wxWidgets se constituie într-un se de instrumente C++ ce permit crearea de

interfaţe grafice GUI (Graphical User Interface) în C++. Aceste clase sunt open source şi

cross-platform. aplicaţiile wxWidgets pot rula pe toate sub toate sistemele de operare

reprezentative: Linux, Windows, Unix si Mac. Proiectul a fost demarat de către 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 fişiere#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"));}

Desfăşurarea lucrării:

1. Se rulează exemplele din secţiunea teoretică

2. Se continuă cu exemplele corespunzătoare din secţiunea TESTE

Page 35: POO - C++ - indrumar laborator

LABORATORUL NR.13

UTILIZAREA CLASELOR WXWIDGETS (II)

Scop: Familiarizarea cu uneltele de dezvoltare a interfeţelor grafice

Consideraţii teoretice:

În vederea realizării interfeţelor grafice este necesară utilizarea metodelor (din cadrul claselor date) ce asigură

gestiunea evenimentelor la nivel de aplicaţie.

Ex:Realizarea unui mic formular utilizând wxFormBuilder

gui.h --wxWidgets license (www.wxwidgets.org) -- fişier generat de wxFormBuilder - necesar înţegerii

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__

Page 36: POO - C++ - indrumar laborator

gui.cpp - wxWidgets license (www.wxwidgets.org) -- fişier generat de wxFormBuilder - necesar înţegerii

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 );

Page 37: POO - C++ - indrumar laborator

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();}

Desfăşurarea lucrării:

1. Se lansează wxFormBuilder şi se construieşte interfaţa

2. Se lansează CodeLite şi se adaugă metodele ce reprezintă răspunsul la evenimente

3. Se compilează şi link-editează

Page 38: POO - C++ - indrumar laborator

LABORATORUL NR.14

TESTE

Scop: Testarea cunoştinţelor

TEST#1

Se dau următoarele 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;}

class C3: protected A1 { int x3,y3; protected: int s3,t3; public: C3():A1() {afis("CONSTRUCTOR_0"); } C3(char *numevar1):A1(numevar1) {afis("CONSTRUCTOR_1"); } C3(char *numevar1,int x11,int y11,int s33): A1(numevar1,x11,y11) {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;}

//1. Ce se afişează în urma execuţiei ? 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. Modificați clasa A1 astfel încât la fiecare apel al vreunui constructor sau al destructorului să afișeze numărul total al obiectelor instanțiate. Adăugaţi 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])? Explicaţi!

3.2. Este posiblil asignarea „d[1]=&g2”? Dar invers (g2=*d[1])? Explicaţi!

3.3. Este posiblil asignarea „d[2]=&m2”? Dar invers (m2=*d[2])? Explicaţi!

3.4. Este posiblil asignarea „e[0]=w2”;? Dar invers? Explicaţi!

3.5. Este posiblil asignarea „e[1]=g2”;? Dar invers?Explicaţi!

3.6. Este posiblil asignarea „e[2]=m2”;? Dar invers?Explicaţi!

4. Se dă o clasă ce conține coordonatele x,y ale

Page 39: POO - C++ - indrumar laborator

unui punct într-un plan. Să se supraîncarce:4.1. Un operator pentru calculul distanței dintre două puncte. 4.2. Un operator ce întoarce un nou obiect ce

conține coordonatele punctului la jumătatea distanței dintre cele două puncte.

TEST #2Se dau următoarele 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;}

class C3: protected A1 { int x3,y3; protected: int s3,t3; public: C3():A1() {afis("CONSTRUCTOR_0"); } C3(char *numevar1):A1(numevar1) {afis("CONSTRUCTOR_1"); } C3(char *numevar1,int x11,int y11,int s33): A1(numevar1,x11,y11) {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;}

//1. Ce se afişează în urma execuţiei ? 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. Modificați clasele astfel încât să contorizeze numărul obiectelor ce au utilizat la instanțiere constructori cu un singur parametru. Adăugaţi 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])? Explicaţi!

3.2. Este posiblil asignarea „d[1]=&g2”? Dar invers (g2=*d[1])? Explicaţi!3.3. Este posiblil asignarea „d[2]=&m2”? Dar invers (m2=*d[2])? Explicaţi!3.4. Este posiblil asignarea „e[0]=w2”;? Dar invers? Explicaţi!3.5. Este posiblil asignarea „e[1]=g2”;? Dar invers?Explicaţi!3.6. Este posiblil asignarea „e[2]=m2”;? Dar invers?Explicaţi!

4. Se dă o clasă ce conține coordonatele x,y

ale vârfurilor unui dreptunghi. Să se supraîncarce:

4.1. Un operator pentru calculul ariei de intersecție a două obiecte. 4.2. Un operator ce întoarce un nou obiect ce conține vârfurile drepunghiului rezultat în urma intersecției a două obiecte.

Page 40: POO - C++ - indrumar laborator

TEST #3

Se dau următoarele 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;}

class C3: protected A1 { char *numevar; int x3,y3; protected: int s3,t3; public: C3(char *numevar1):A1(numevar1) {numevar=new char[100]; strcpy(numevar,numevar1); afis("CONSTRUCTOR_1"); } C3(char *numevar1,int x11,int y11,int s33): A1(numevar1,x11,y11) {numevar=new char[100];

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 afişează în urma execuţiei ? 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. Adăugaţi câte un contor pentru numărul de obiecte instanţiate, pentru fiecare clasă în parte (adăugaţi direct pe codul scris şi rescrieţi numai metodele modificate). Afişaţi acest număr î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”;? Explicaţi!

3.2. Este posiblil asignarea „d[2]=m2”;? Explicaţi!

3.3. În cazul în care este posibilă asignarea ce se afişează în urma apelului metodei afis(“d[i]”) , i=0,1 sau 2 ? Explicaţi!

4. Sa se scrie o clasa ce contine un operator supraîncarcat pentru operatia de concatenarea a doi vectori cu numere de tip double si un operator supaincarcat pentru operatia de ordonare crescatoare a elementelor vectorului.

Page 41: POO - C++ - indrumar laborator

TEST #4

Se dau următoarele 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;}

class C3: public A1 { int x3,y3; protected: int s3,t3; public: C3():A1() {afis("CONSTRUCTOR_0"); } C3(char *numevar1):A1(numevar1) {afis("CONSTRUCTOR_1"); } C3(char *numevar1,int x11,int y11,int s33): A1(numevar1,x11,y11) {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;}

//1. Ce se afişează în urma execuţiei ? int main(int argc, char* argv[]){C3 *a1, b2[2]; {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;}

R 2. Modificați clasa A1 astfel încât la fiecare apel al vreunui constructor sau al destructorului să afișeze numărul total al obiectelor instanțiate. Adăugaţi 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])? Explicaţi!

3.2. Este posiblil asignarea „d[1]=&g2”? Dar invers (g2=*d[1])? Explicaţi!

3.3. Este posiblil asignarea „d[2]=&m2”? Dar invers (m2=*d[2])? Explicaţi!

3.4. Este posiblil asignarea „e[0]=w2”;? Dar invers? Explicaţi!

3.5. Este posiblil asignarea „e[1]=g2”;? Dar invers?Explicaţi!

3.6. Este posiblil asignarea „e[2]=m2”;? Dar invers?Explicaţi!

.4. Se dă o clasă ce conține coordonatele x,y ale unui punct într-un plan. Să se supraîncarce:4.1. Un operator pentru calculul distanței dintre două puncte. 4.2. Un operator ce întoarce un nou obiect ce conține coordonatele punctului la jumătatea distanței dintre cele două puncte.

Page 42: POO - C++ - indrumar laborator

TEST #5

Se dau următoarele 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;}

class C3: public A1 { int x3,y3; public: int s3,t3; public: C3():A1() {afis("CONSTRUCTOR_0"); } C3(char *numevar1):A1(numevar1) {afis("CONSTRUCTOR_1"); } C3(char *numevar1,int x11,int y11,int s33): A1(numevar1,x11,y11) {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;}

//1. Ce se afişează în urma execuţiei:

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;}

Rint 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.Explicaţi dacă sunt sa nu posibile urmăroarele asignări: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 şir de caractere (această clasă va conţine un pointer la un şir de numere de tip real). Să se supraîncarce un operator care să permită

obţinerea unui obiect având şirul de numere

ordonat crescător (se va scrie declaraţia clasei,

explicitarea unui constructor, explicitarea

destructorului şi explicitarea funcţiei operator).

Page 43: POO - C++ - indrumar laborator

TEST #6

Se dau următoarele clase: #include <conio.h>#include <iostream.h>#include <iomanip.h>#include <string.h>

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(); };

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 afişează în urma execuţiei ?

int main(){C3 *m2;

{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;}

2.Este posibilă execuţia următoarelor instrucţiuni? Explicaţi 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 afişează în urma execuţiei ?void A1::tipar() {cout<<”xa=”<<setw(7)<<setfill('^')<<hex<<xa<<endl;}void B2::tipar() {cout<<setw(7)<<setfill('~')<<”xb=”<<hex<<xb<<endl;}void C3::tipar() {cout<<”xc=”<<setw(7)<<setfill('#')<<hex<<xc<<endl;}

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",45); B2 r2("var-r2",46,47); C3 r3("var-r3",48,49,43,44);m[0]=&r1;m[1]=&r2; m[2]=&r3; m[0]->tipar(); m[1]->tipar(); m[2]->tipar(); getch();}

4. Se dă o clasă pentru gestiunea operaţiilor cu date calendaristice. Clasa conţine o variabilă ce memorează numărul se minute raportat la 31.12,1899, ora 24:00:00.000. Să se supraîncarce un operator care să permită adunare cu un anumit număr de ore (se va scrie declaraţia clasei, explicitarea unui constructor şi

Page 44: POO - C++ - indrumar laborator

explicitarea funcţiei operator).

TEST #7

Se dau următoarele clase:

#include <conio.h>#include <iostream.h>#include <iomanip.h>#include <string.h>

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 *numevar1) {xa=0;ya=0;strcpy(numevar,numevar1);afis("CONSTRUCTOR_1");} A1(char *numevar1, int x1) {xa=x1;ya=0;;strcpy(numevar,numevar1);afis("CONSTRUCTOR_2");} A1(char *numevar1,int x1, int y1) {xa=x1;ya=y1;;strcpy(numevar,numevar1);afis("CONSTRUCTOR_3");} ~A1() {afis("DESTRUCTOR");} virtual void afis(char *str); virtual void tipar(); };

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(); };

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”);} 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<<e;}

1. Ce se afişează în urma execuţiei ?

int main(){ A1 *r1;

{A1 w2("d1",13,12),d1[2]; C3 m1("m1"); r1=new A1("r1",11,61); B2 g2("g2"); } delete r1; getch(); return 0;}

R:2.Este posibilă execuţia următoarelor instrucţiuni? Explicaţi 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 afişează în urma execuţiei ?void A1::tipar() {cout<<”xa=”<<setw(7)<<setfill('*')<<hex<<xa<<endl;}void B2::tipar() {cout<<setw(7)<<setfill('*')<<”xb=”<<hex<<xb<<endl;}void C3::tipar() {cout<<”xc=”<<setw(7)<<setfill('*')<<hex<<xc<<endl;}

iar class C3:public A1 in loc de class C3:protected A1

void main() {A1 *m[3],r1("var-r1",15); B2 r2("var-r2",2,3); C3 r3("var-r3",4,5,6,7); m[0]=&r3;m[1]=&r2; m[2]=&r1; m[0]->tipar(); m[1]->tipar(); m[2]->tipar(); getch();}

4. Se dă o clasă ce gestionează elementele unui şir de caractere (această clasă va conţine un pointer la un şir de caractere). Să se supraîncarce un operator care să permită

Page 45: POO - C++ - indrumar laborator

adăugarea unui caracter la sfârsitul şirului (se va scrie declaraţia clasei, explicitarea unui constructor, explicitarea destructorului şi

explicitarea funcţiei operator).

Page 46: POO - C++ - indrumar laborator

TEST #8

Se dau următoarele clase:

#include <conio.h>#include <iostream.h>#include <iomanip.h>#include <string.h>

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(); };

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 afişează în urma execuţiei ?int main() {A1 d1[2],*r1; 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;}

2.Este posibilă execuţia următoarelor instrucţiuni? Explicaţi 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 afişează în urma execuţiei ?void A1::tipar() {cout<<”xa=”<<setw(7)<<setfill('^')<<hex<<xa<<endl;}void B2::tipar() {cout<<setw(7)<<setfill('~')<<”xb=”<<hex<<xb<<endl;}void C3::tipar() {cout<<”xc=”<<setw(7)<<setfill('#')<<hex<<xc<<endl;}

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();}

4. Se dă o clasă pentru gestiunea operaţiilor cu date calendaristice. Clasa conţine o variabilă ce memorează numărul se minute raportat la 31.12.1899, ora 24:00:00.000. Să se supraîncarce un operator care să permită adunare cu un anumit număr de zile (se va scrie declaraţia clasei, explicitarea unui constructor şi explicitarea funcţiei operator).

Page 47: POO - C++ - indrumar laborator

TEST #9

Se dau următoarele clase:

#include <conio.h>#include <iostream.h>#include <iomanip.h>#include <string.h>

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(); };

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 afişează în urma execuţiei ?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;}

.2.Este posibilă execuţia următoarelor instrucţiuni? Explicaţi 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 afişează în urma execuţiei ?void A1::tipar() {cout<<”xa=”<<setw(7)<<setfill('^')<<hex<<xa<<endl;}void B2::tipar() {cout<<setw(7)<<setfill('~')<<”xb=”<<hex<<xb<<endl;}void C3::tipar() {cout<<”xc=”<<setw(7)<<setfill('#')<<hex<<xc<<endl;}

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();}

4. Se dă o clasă pentru gestiunea operaţiilor cu date calendaristice. Clasa conţine o variabilă ce memorează numărul se minute raportat la 31.12.1899, ora 24:00:00.000. Să se supraîncarce un operator care să permită adunare cu un anumit număr de secunde (se va scrie declaraţia clasei, explicitarea unui constructor şi explicitarea funcţiei operator).

Page 48: POO - C++ - indrumar laborator

TEST #10

Se dau următoarele clase:

#include <conio.h>#include <stdio.h>#include <string.h>

class A1{int x1,y1; char *numevar; protected: int s1; public: int t1; A1() {numevar=new char[100];strcpy(numevar,"N/A"); x1=0;y1=0;s1=-1;t1=-1;afis("CONSTRUCTOR_0 A1");} A1(char *numevar1) {numevar=new char[100]; strcpy(numevar,numevar1); x1=0;y1=0;s1=-1;t1=-1;afis("CONSTRUCTOR1 A1");} A1(char *numevar1,int x11, int y11) {numevar=new char[100]; strcpy(numevar,numevar1); x1=x11; y1=y11; s1=0;t1=0;afis("CONSTRUCTOR2 A1");} ~A1() {afis("DESTRUCTOR A1");delete[] numevar;} virtual void afis(char *str); private: void calc(); };

void A1::afis(char *str){printf("\n %s -- numevar:%s x1=%d y1=%d s1=%d t1=%d",str,numevar,x1,y1,s1,t1);}

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); x2=0; y2=0; s2=0; t2=0; s1=-2;t2=-2; afis("CONSTRUCTOR1 B2"); } 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"); } ~B2() {afis("DESTRUCTOR B2");delete[] numevar;} void afis(char *str); };

void B2::afis(char *str) {printf("\n %s -- numevar:%s x2=%d y2=%d s2=%d t2=%d",str,numevar,x2,y2,s2,t2);}

class C3: protected A1 { char *numevar; int x3,y3; protected: int s3,t3; public: C3(char *numevar1):A1(numevar1) {numevar=new char[100]; strcpy(numevar,numevar1); x3=0;y3=0;s3=0;t3=0;s1=-3;t1=-3;

afis("CONSTRUCTOR1 C3"); } 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);}

1. Ce se afişează în urma execuţiei ? int main(int argc, char* argv[]){C3 *m2; A1 *r1; {A1 d1[2],w1("d1"),w2("d1",5,4); B2 *g1,g2("g2"); C3 m1("m1"); g1=new B2("g1",21,17,19); m2=new C3("m2",101,32,54); delete m2; r1=new A1("r1",11,61); delete g1; } delete r1; getch(); return 0;}2.1.Ce va afişa funcţia afis(char *str) dacă nu este apelată ultima în cadrul unui constructor?

2.2. Ce va afişa funcţia afis(char *str) dacă nu este apelată prima în cadrul unui destructor?

2.3 De ce nu a putut fi afişat numevar şi pentru construcorul implicit?

2.4 Ce legătură există între variabila numevar din clasa de bază şi cea declarată în clasele derivate?2.5.Pentru variabilele declarate la pct.1. Este posibil accesul lui g1->t1? Explicaţi!

Dar al lui m1->t1 ? Explicaţi! 3. Adăugaţi câte un contor pentru numărul de obiecte instanţiate, pentru fiecare clasă în parte (adăugaţi direct pe codul scris şi rescrieţi numai metodele modificate). Afişaţi acest număr în cadrul constructorilor şi destructorilor.4.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;}

4.1. Este posiblil asignarea „d[1]=g2”;? Explicaţi!

.4.2. Este posiblil asignarea „d[2]=m2”;? Explicaţi!.4.3. În cazul în care este posibilă asignarea ce

Page 49: POO - C++ - indrumar laborator

se afişează în urma apelului metodei afis(“d[i]”) , i=0,1 sau 2 ? Explicaţi!

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