Programare Orientată pe Obiect Lucrarea de laborator Nr. 6...

12
Ioana Dogaru - Programare Orientata pe Obiecte 1 Programare Orientată pe Obiect Lucrarea de laborator Nr. 6 Funcţii virtuale şi polimorfism Cuvantul cheie virtual este folosit: înaintea numelui clasei de bază la definirea claselor derivate pentru cazul de moştenire multiplă, în care o clasă este moştenită indirect de mai multe ori, evitându-se astfel crearea de copii multiple care generau ambiguităţi. la definirea funcţiilor virtuale care reprezintă un mecanism pentru implementarea polimorfismului în clasele derivate. Două sau mai multe obiecte sunt polimorfe dacă au asemănări, dar totuşi sunt diferite. Supraîncărcarea operatorilor şi a funcţiilor sunt exemple de polimorfism pentru că o singură entitate referă două sau mai multe caracteristici diferite. Altfel spus, polimorfismul permite definirea unei interfeţe comune pentru mai multe metode specifice diferitelor funcţionalităţi. 1. Conversia pointerilor între clase de bază şi derivate. Funcţii virtuale. Conversia unui pointer la o clasă derivată în pointer la o clasă de bază a acesteia este implicită, dacă derivarea este de tip public şi nu există ambiguităţi. Rezultatul conversiei este un pointer la subobiectul din clasa de bază al obiectului din clasa derivată. Conversia inversă, a unui pointer la o clasă de bază în pointer la derivată nu este admisă implicit. O astfel de conversie se poate forţa explicit prin operatorul de conversie cast. Rezultatul unei astfel de conversii este însă nedeterminat, de cele mai multe ori provocând erori de execuţie. Exemplificare: class Baza { /* */ }; class Derivata:public Baza { /* */ }; void main(){ Derivata ob_d; Baza* p_ob_b = &ob_d; // corect, conversie implicita Baza ob_b; Derivata* p_ob_d = &ob_b;// eroare la compilare, nu se poate //converti implicit de la class Baza* la class Derivata* Derivata* p_ob_d =(Derivata*)&ob_b; // se compileaza corect, dar //rezultatul este nedeterminat } O funcţie virtuală este o funcţie care este declarată de tip virtual în clasa de bază şi redefinită într-o clasă derivată.

Transcript of Programare Orientată pe Obiect Lucrarea de laborator Nr. 6...

Page 1: Programare Orientată pe Obiect Lucrarea de laborator Nr. 6 ...atm.neuro.pub.ro/radu_d/html/09_10/poo2009/LaboratorPOO6.pdf · class Baza { /* */ }; ... Apelurile rezolvate în timpul

Ioana Dogaru - Programare Orientata pe Obiecte

1

Programare Orientată pe Obiect Lucrarea de laborator Nr. 6

Funcţii virtuale şi polimorfism Cuvantul cheie virtual este folosit:

� înaintea numelui clasei de bază la definirea claselor derivate pentru cazul de moştenire multiplă, în care o clasă este moştenită indirect de mai multe ori, evitându-se astfel crearea de copii multiple care generau ambiguităţi.

� la definirea funcţiilor virtuale care reprezintă un mecanism pentru implementarea polimorfismului în clasele derivate.

Două sau mai multe obiecte sunt polimorfe dacă au asemănări, dar totuşi sunt diferite. Supraîncărcarea operatorilor şi a funcţiilor sunt exemple de polimorfism pentru că o singură entitate referă două sau mai multe caracteristici diferite. Altfel spus, polimorfismul permite definirea unei interfeţe comune pentru mai multe metode specifice diferitelor funcţionalităţi. 1. Conversia pointerilor între clase de bază şi derivate. Funcţii virtuale.

Conversia unui pointer la o clasă derivată în pointer la o clasă de bază a acesteia este

implicită, dacă derivarea este de tip public şi nu există ambiguităţi. Rezultatul conversiei este un pointer la subobiectul din clasa de bază al obiectului din clasa derivată.

Conversia inversă, a unui pointer la o clasă de bază în pointer la derivată nu este admisă

implicit. O astfel de conversie se poate forţa explicit prin operatorul de conversie cast. Rezultatul unei astfel de conversii este însă nedeterminat, de cele mai multe ori provocând

erori de execuţie. Exemplificare:

class Baza { /* */ }; class Derivata:public Baza { /* */ }; void main(){

Derivata ob_d; Baza* p_ob_b = &ob_d; // corect, conversie implicita Baza ob_b; Derivata* p_ob_d = &ob_b;// eroare la compilare, nu se poate //converti implicit de la class Baza* la class Derivata* Derivata* p_ob_d =(Derivata*)&ob_b; // se compileaza corect, dar

//rezultatul este nedeterminat } O funcţie virtuală este o funcţie care este declarată de tip virtual în clasa de bază şi redefinită într-o clasă derivată.

Page 2: Programare Orientată pe Obiect Lucrarea de laborator Nr. 6 ...atm.neuro.pub.ro/radu_d/html/09_10/poo2009/LaboratorPOO6.pdf · class Baza { /* */ }; ... Apelurile rezolvate în timpul

Ioana Dogaru - Programare Orientata pe Obiecte

2

Redefinirea unei funcţii virtuale într-o clasă derivată domină (override) definiţia funcţiei în clasa de bază. Mecanismul de virtualitate se manifestă numai în cazul apelului funcţiilor prin intermediul pointerilor. Reguli:

� Atunci când o funcţie normală (care nu este virtuală) este definită într-o clasă de bază şi redefinită în clasele derivate, la apelul acesteia ca funcţie membră a unui obiect pentru care se cunoaşte un pointer, se selectează funcţia după tipul pointerului, indiferent de tipul obiectului al cărui pointer se foloseşte (obiect din clasa de bază sau obiect din clasa derivată).

� Dacă o funcţie este definită ca funcţie virtuală în clasa de bază şi redefinită în clasele derivate, la apelul acesteia ca funcţie membră a unui obiect pentru care se cunoaşte un pointer, se selectează funcţia după tipul obiectului, nu al pointerului. Sunt posibile mai multe situaţii:

- Dacă obiectul este din clasă de bază nu se poate folosi un pointer la o clasă derivată. - Dacă obiectul este de tip clasă derivată şi pointerul este pointer la clasă derivată, se

selectează funcţia redefinită în clasa derivată respectivă. - Dacă obiectul este de tip clasă derivată, iar pointerul folosit este un pointer la o clasă de

bază a acesteia, se selectează funcţia redefinită în clasa derivată corespunzătoare tipului obiectului.

Acesta este mecanismul de virtualitate şi el permite implementarea polimorfismului în clasele derivate. O funcţie redefinită într-o clasă derivată domină funcţia virtuală corespunzătoare din clasa de bază şi o înlocuieşte chiar dacă tipul pointerului cu care este accesată este pointer la clasa de bază. În apelul ca funcţie membră a unui obiect dat cu numele lui, funcţiile virtuale se comportă normal, ca funcţii redefinite. Nu pot fi declarate funcţii virtuale funcţiile nemembre, constructorii, funcţiile friend. Funcţia declarată virtual în clasa de bază acţionează ca o descriere generică prin care se defineşte interfaţa comună, iar funcţiile redefinite în clasele derivate precizează acţiunile specifice fiecărei clase derivate aşa cum se va ilustra în exerciţiul următor: Exercitiul 1.

Entităţile dreptunghi, triunghi sunt corelate între ele prin aceea că toate sunt forme geometrice, deci ele au în comun conceptul de formă geometrică.

Pentru a reprezenta un triunghi sau dreptunghi într-un program, trebuie ca aceste clase, care reprezintă fiecare o formă geometrică în parte împreună cu proprietăţile sale, să aibă în comun clasa care reprezintă în general o formă geometrică.

Să se definească o clasă de bază CFigura. Derivaţi din această clasă, corespunzător pentru cele doua figuri geometrice, clasele CTriunghi şi CDreptunghi, şi completaţi pentru fiecare clasă în parte datele membre necesare, constructorii, destructorii, funcţia de calcul al ariei care va determina aria si va afişa numele figurii corespunzatoare.

În funcţia main() creaţi câte un obiect triunghi şi dreptunghi şi afişaţi aria fiecăruia;

Page 3: Programare Orientată pe Obiect Lucrarea de laborator Nr. 6 ...atm.neuro.pub.ro/radu_d/html/09_10/poo2009/LaboratorPOO6.pdf · class Baza { /* */ }; ... Apelurile rezolvate în timpul

Ioana Dogaru - Programare Orientata pe Obiecte

3

class CDreptunghi: public CFigura{ public: CDreptunghi( int a, int b) {width = a; height = b; } int area () { cout << "Aria dreptunghiului :" <<endl; return (width * height); } };

class CTriunghi: public CFigura{ public: CTriunghi( int a, int b) {width = a; height = b;} int area () { cout << "Aria triunghiului :" <<endl;

CFigura (Clasa de baza)

CDreptunghi (Clasa derivata) CTriunghi

(Clasa derivata)

public public

class CFigura { protected: int width, height; public: CFigura( int a=0, int b=0) { width = a; height = b; } int area() { cout << "Aria figurii de baza :" <<endl; return 0; } };

Page 4: Programare Orientată pe Obiect Lucrarea de laborator Nr. 6 ...atm.neuro.pub.ro/radu_d/html/09_10/poo2009/LaboratorPOO6.pdf · class Baza { /* */ }; ... Apelurile rezolvate în timpul

Ioana Dogaru - Programare Orientata pe Obiecte

4

return (width * height / 2); } }; Experimente: a) In clasa CFigura s-a folosit tipul de date protected. (pentru int width, height). Explicati acest lucru. b) In functia main() se introduce urmatoarea secventa: CFigura *p; CDreptunghi dr(12,14); CTriunghi tr(20,40); p = &dr; // adresa obiectului dreptunghi p->area(); //aria dreptunghiului p = &tr; // adresa obiectului triunghi p->area(); //aria triunghiului Ce se obtine la executia programului? Explicati. c) Se modifica clasa CFigura folosind cuvantul cheie virtual pentru functia int area() care devine: virtual int area(). Se reia executia programului. Ce se obtine la executia programului? Explicati. d) Afisati rezultatul celor doua arii calculate la punctul c) e) Sa se foloseasca alocarea dinamica pentru obiecte de clasa CFigura, CDreptunghi si respectiv CTriunghi; Sa se afiseze aria pentru fiecare tip de obiect in parte. f) Sa se reia exemplul de la punctul e) in care alocarea dinamica foloseste pointer la clasa de baza. Folosiţi acest pointer pentru a crea dinamic câte un obiect de tipul claselor derivate şi afişaţi pentru fiecare obiect în parte aria şi tipul său. Cum se explica rezultatul obtinut; Sa se stearga cuvantul cheie virtual din clasa CFigura folosit pentru functia area() si sa se reia executia programului de la punctul f). Cum explicati rezultatul obtinut? 2. Moştenirea funcţiilor virtuale

Atributul virtual se moşteneşte pe tot parcursul derivării. Cu alte cuvinte, dacă o funcţie este declarată de tip virtual în clasa de bază, funcţia redefinită într-o clasă derivată este funcţie de tip virtual în mod implicit (fără să fie nevoie de declaraţie explicită virtual).

Acest lucru înseamnă că, dacă această clasă derivată serveşte pentru definirea unei noi derivări, funcţia va fi moştenită de asemenea de tip virtual. Pot să apară şi alte situaţii în moştenirea funcţiilor

Page 5: Programare Orientată pe Obiect Lucrarea de laborator Nr. 6 ...atm.neuro.pub.ro/radu_d/html/09_10/poo2009/LaboratorPOO6.pdf · class Baza { /* */ }; ... Apelurile rezolvate în timpul

Ioana Dogaru - Programare Orientata pe Obiecte

5

virtuale. De exemplu, dacă o funcţie virtuală nu este redefinită într-o clasă derivată, atunci se foloseşte funcţia moştenită din clasa de bază şi pentru obiecte de tip clasă derivată

Exercitiul 2:

Reluaţi exerciţiul anterior şi derivaţi din clasa CTriunghi o nouă clasă, CTriunghiColorat, care să conţină, în plus, culoarea dată printr-un număr întreg. În funcţia main() creaţi în mod dinamic un obiect tip CTriunghiColorat şi afişaţi aria obiectului. (Observatie: clasele definite anterior vor avea toate functiile constructor necesare definite)

3. Destructori virtuali

Destructorii pot fi declaraţi de tip virtual, şi această declaraţie este absolut necesară în situaţia în care se dezalocă un obiect de tip clasă derivată folosind pointer la o clasă de bază a acesteia.

Exerciţiul 3:

Completaţi clasele CFigura, CTriunghi si CDreptunghi cu functiile destructor, fiecare avand un mesaj specific pentru fiecare tip in parte. Se va crea un obiect tip clasa derivate creat prin pointer la clasa de baza. Se va executa programul.

Mesajele afişate evidenţează faptul că la ştergerea unui obiect tip clasă derivată creat prin pointer la clasa de bază a fost şters numai un subobiect al acestuia, subobiectul din clasa de bază. Acest lucru face ca memoria liberă (heap) să rămână ocupată în mod inutil (cu partea de date a clasei derivate), deşi se intenţiona eliminarea completă din memorie a obiectului creat.

Exerciţiul 4:

Se va declara destructorul din clasa de bază (CFigura) de tip virtual. Ce mesaje se obţin la rularea programelor?

4. Clase abstracte De cele mai multe ori funcţia declarată de tip virtual în clasa de bază nu defineşte o acţiune semnificativă şi este neapărat necesar ca ea să fie redefinită în fiecare din clasele derivate (de exemplu, funcţia area() în clasa CFigura). Pentru ca programatorul să fie obligat să redefinească o funcţie virtuală în toate clasele derivate în care este folosită această funcţie, se declară funcţia respectivă virtuală pură. O funcţie virtuală pură este o funcţie care nu are definiţie în clasa de bază, iar declaraţia ei arată în felul următor:

virtual tip_returnat nume_functie(lista_arg) = 0;

O clasă care conţine cel puţin o funcţie virtuală pură se numeşte clasă abstractă. Deoarece o clasă abstractă conţine una sau mai multe funcţii pentru care nu există definiţii (funcţii virtuale pure), nu pot fi create instanţe (obiecte) din acea clasă, dar pot fi creaţi pointeri şi referinţe la astfel de clase abstracte. O clasă abstractă este folosită în general ca o clasă fundamentală, din care se construiesc alte clase prin derivare.

Page 6: Programare Orientată pe Obiect Lucrarea de laborator Nr. 6 ...atm.neuro.pub.ro/radu_d/html/09_10/poo2009/LaboratorPOO6.pdf · class Baza { /* */ }; ... Apelurile rezolvate în timpul

Ioana Dogaru - Programare Orientata pe Obiecte

6

Orice clasă derivată dintr-o clasă abstractă este, la rândul ei clasă abstractă (şi deci nu se pot crea instanţe ale acesteia) dacă nu redefinesc toate funcţiile virtuale pure moştenite. Dacă o clasă redefineşte toate funcţiile virtuale pure ale claselor ei de bază, devine clasă normală (ne-abstractă) şi pot fi create instanţe (obiecte) ale acesteia.

Exerciţiul 5:

Modificaţi programele anterioare astfel încât clasa CFigura să fie abstractă. Ce modificări trebuie aduse programelor pentru obţinerea unei funcţionări corecte?

5. Polimorfismul Una din caracteristicile importante ale programării orientate pe obiecte este aceea că permite definirea unei interfeţe comune pentru mai multe metode specifice diferitelor funcţionalităţi.

Această comportare, care asigură simplificarea şi organizarea sistemelor de programe complexe, este cunosută sub numele de polimorfism. Polimorfismul introdus prin mecanismul de virtualitate este polimorfism la nivel de execuţie, care permite legarea târzie (late binding) între evenimentele din program, în contrast cu legarea timpurie (early binding), proprie apelurilor funcţiilor normale (nevirtuale). Intercorelarea (legarea) timpurie se referă la evenimentele care se desfăşoară în timpul compilării şi anume apeluri de funcţii pentru care sunt cunoscute adresele de apel: funcţii normale, funcţii supraîncărcate, operatori supraîncărcaţi, funcţii membre nevirtuale, funcţii friend. Apelurile rezolvate în timpul compilării beneficiază de o eficienţă ridicată. Termenul de legare târzie se referă la evenimente din timpul execuţiei. În astfel de apeluri, adresa funcţiei care urmează să fie apelată nu este cunoscută decât în momentul execuţiei programului.

Funcţiile virtuale sunt evenimente cu legare târzie: accesul la astfel de funcţii se face prin pointer la clasa de bază, iar apelarea efectivă a funcţiei este determinată în timpul execuţiei de tipul obiectului indicat, pentru care este cunoscut pointerul la clasa sa de bază. Avantajul principal al legării târzii (permisă de polimorfismul asigurat de funcţiile virtuale) îl constitue simplitatea şi flexibilitatea programelor rezultate. Dezavantajul cel mai important este timpul suplimentar necesar selecţiei funcţiei apelate efectiv din timpul execuţiei, ceea ce conduce la un timp de execuţie mai mare al programelor.

Exerciţiul 6: Se dă următorul program: class B{ public: void f(){ cout<<”f() din B\n”; } virtual void g(){cout<<”g() din B\n”; } }; class D1:public B{ public: void f(){ cout<<”f() din D1\n”; } void g(){cout<<”g() din D1\n”; } }; class D2:public B{ public: void f(){ cout<<”f() din D2\n”; } void g(){cout<<”g() din D2\n”; }

Page 7: Programare Orientată pe Obiect Lucrarea de laborator Nr. 6 ...atm.neuro.pub.ro/radu_d/html/09_10/poo2009/LaboratorPOO6.pdf · class Baza { /* */ }; ... Apelurile rezolvate în timpul

Ioana Dogaru - Programare Orientata pe Obiecte

7

}; void fv1(){ B* pb = new B; D1* pd1 = new D1; D2* pd2 = new D2; B* pb1 = pd1; B* pb2 = pd2;

// Obiect B, pointer din B* pb->f(); pb->g(); // Obiecte D1, D2, pointeri D1*, D2* pd1->f(); pd2->f(); pd1->g(); pd2->g(); // Obiecte D1, D2, pointeri B*, B* pb1->f(); pb2->f(); pb1->g(); pb2->g(); delete pb; delete pd1; delete pd2;

} Observaţi comportamentul funcţiilor virtuale cu ajutorul mesajelor ce vor fi afişate la consolă ? 6. Tratarea exceptiilor Tratarea exceptiilor permite rezolvarea în mod unitar a erorilor de executie. Mecanismul de tratare a exceptiilor din C++ ofera posibilitatea ca o problema care apare într-o functie si aceasta nu o poate rezolva, sa fie definita ca o exceptie, cu speranta ca functia apelata va trata aceasta problema. O functie care doreste sa trateze astfel de probleme va indica acest lucru prin captarea exceptiei respective. Codul care se executa la captare se numeste rutina de tratare a exceptiei (exception handler). Constructia: catch ( /* .. */){// } este numita rutina de tratare a exceptiei (exception handler). Ea este apelata imediat dupa un bloc prefixat de cuvântul cheie try sau dupa o alta rutina de tratare a unei exceptii. Paranteza care urmeaza cuvântului cheie catch contine o declaratie care este folosita ca un argument: aceast declaratie specifica tipul exceptiei de care se ocupa rutina de tratare a erorii si, uneori, numele argumentului. Daca o exceptie (ceea ce însemna o eroare) apare într-un bloc prefixat de specificatorul try, ea este lansata de catre instructiunea throw, dupa care este captata într-o rutina de tratare a exceptiilor (deci în blocul instructiunii catch) si prelucrat .

Page 8: Programare Orientată pe Obiect Lucrarea de laborator Nr. 6 ...atm.neuro.pub.ro/radu_d/html/09_10/poo2009/LaboratorPOO6.pdf · class Baza { /* */ }; ... Apelurile rezolvate în timpul

Ioana Dogaru - Programare Orientata pe Obiecte

8

Blocul try trebuie sa contin acea sectiune a programului în care se doreste sa fie cautate erorile. El poate cuprinde câteva instructiuni într-o functie sau chiar întregul corp al functiei main(), ceea ce înseamna urmarirea erorilor în întregul program. Atunci când o functie genereaza o exceptie, ea nu îsi mai continua executia ca în situatia în care ar apela o functie de tratare a erorii, din care se revine printr-o instructiune return, ci executia este captata în rutina de tratare, dupa care se continua programul cu instructiunile care urmeaza rutinei de tratare a exceptiei.

Exemplul 2: Sa se implementeze mecanismul de tratare a erorilor pentru cazul in care avem impartirea la zero. Rezolvare: #include <iostream> #include <stdexcept> using namespace std; double impartire(int a, int b) { if( b == 0 ) { throw "Impartire la zero!"; } return (a/b); } int main() { int x = 120;

Page 9: Programare Orientată pe Obiect Lucrarea de laborator Nr. 6 ...atm.neuro.pub.ro/radu_d/html/09_10/poo2009/LaboratorPOO6.pdf · class Baza { /* */ }; ... Apelurile rezolvate în timpul

Ioana Dogaru - Programare Orientata pe Obiecte

9

int y = 0; double rez; try { rez = impartire(x, y); cout << rez << endl; }catch (const char* msg) { cerr << msg << endl; } cout<<"Altceva de executat"<<endl;

return 0 ; } Observatii: 1) Se foloseste #include <stdexcept> pentru a putea folosi ierarhia principalelor clase de exceptii; 2) Daca nu ar fi implementat mecanismul de tratare erori, la impartirea la zero programul se va opri in conditii anormale. 3) Cu mecanismul de tratare erori, se afiseaza un mesaj de atentionare, dar programul va functiona in continuare. Exemplul 3: Sa se implementeze o clasa care va trata o situatie anormala aparuta la folosirea in program a unui pointer neintializat. (care nu indica catre o adresa valida de memorie) Solutie: Definim o clasa si o functie care apartine acestei clase care va identifica eroarea si va corecta problema si va aloca corect memoria pentru pointerul folosit. Programul devine: class TratareEroare{

public: void f(int *ptr){ try{ if(0==ptr){ throw runtime_error("Pointer incorect folosit. Nu s-a alocat memorie"); } else *ptr = 10; } catch(runtime_error &er){ cout<<er.what()<<endl; int a; ptr = &a; *ptr=10; } cout<<"Valoarea intreaga indicata de ptr:"<<" " <<*ptr<<endl;

Page 10: Programare Orientată pe Obiect Lucrarea de laborator Nr. 6 ...atm.neuro.pub.ro/radu_d/html/09_10/poo2009/LaboratorPOO6.pdf · class Baza { /* */ }; ... Apelurile rezolvate în timpul

Ioana Dogaru - Programare Orientata pe Obiecte

10

cout<<"Adresa pointerului: "<<ptr<<endl; } }; int main() {

int *p=NULL; //instantiem un obiect al clasei TratareEroare TratareEroare ob; ob.f(p); cout<<"Programul continua..."<<endl; return 0; } La executia programului obtinem:

Observatii:

1. S-a folosit clasa runtime_error si functia membra what() care returneaza informatii despre eroare printr-un sir de caractere.

2. Erorile din runtime_error semnaleaza anomalii din momentul executiei; 3. Blocul catch informeaza despre aparitia in program a unei situatii anormale si repara acest

lucru. 4. Se continua apoi executia normala a programului;

Exemplul 4: Se va implementa tratarea de erori in cazul in care se doreste folosirea in program de numere intregi cu valori mai mari decat zero. Solutie: class NumarIntPozitiv { private: int value; // numai valori pozitive (>0) public: NumarIntPozitiv(int value = 1); void setValue(int value); int getValue() const; }; NumarIntPozitiv::NumarIntPozitiv(int value) { setValue(value); } void NumarIntPozitiv::setValue(int v) {

Page 11: Programare Orientată pe Obiect Lucrarea de laborator Nr. 6 ...atm.neuro.pub.ro/radu_d/html/09_10/poo2009/LaboratorPOO6.pdf · class Baza { /* */ }; ... Apelurile rezolvate în timpul

Ioana Dogaru - Programare Orientata pe Obiecte

11

if (v > 0) { value = v; } else { throw invalid_argument("Valoarea trebuie sa fie mai mare decat zero!."); // este nevoie de header <stdexcept> } } int NumarIntPozitiv::getValue() const { return value; } int main() { NumarIntPozitiv nr1(18); cout << nr1.getValue() << endl; //secventa nu declanseaza mecanismul de tratare erori try { NumarIntPozitiv nr3(-10); cout << "Se verifica numarul intreg..." << endl; // Exceptia este captata. // Se apeleaza blocul catch. cout << nr3.getValue() << endl; // Daca nu este nicio exceptie se continua instructiunile } catch (invalid_argument & ex) { // need <stdexcept> cout << "Exceptie: " << ex.what() << endl; // Se continua cu urmatoarele instructiuni dupa try-catch } cout<<"Instructiuni dupa rezolvarea exceptiei"<<endl; return 0; }

Experimente : a) In codul de mai sus se va modifica instructiunea NumarIntPozitiv nr3(-10); care va deveni NumarIntPozitiv nr3(10); Sa se execute codul, sa se observe si sa se interpreteze rezultatele.

Page 12: Programare Orientată pe Obiect Lucrarea de laborator Nr. 6 ...atm.neuro.pub.ro/radu_d/html/09_10/poo2009/LaboratorPOO6.pdf · class Baza { /* */ }; ... Apelurile rezolvate în timpul

�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������