Documente Academic
Documente Profesional
Documente Cultură
CURS 5 PROGRAMARE II
CURS ANTERIOR
Suprancrcarea operatoriilor Funcii membre Funcii prietene
Suprancrcarea operatoriilor
Asignare Binari Prescurtai Relaionali Incrementare/decrementare Indexare
CUPRINS
Suprancrcarea operatoriilor unari Suparncrcarea operatorilor
Conversii de tip
Excepii
Aruncarea excepiilor Prinderea exceptiilor Constructori
Exemplu Operatorul !
class String { public: bool operator!() const; ... }; class String { friend bool operator!( const String & ); ... }
CONVERSI DE TIP
Reguli La evaluarea unei expresii se efectueaz conversii sistematice de la tipurile ntregi scurte la tipul int sau unsigned int. Apoi, pentru fiecare operand, dac operanzii au tipuri diferite, se efectueaz conversia necesar pentru a obine ambii operanzi de acelai tip. La atribuire se efectueaz conversia valorii atribuite la tipul operandului care primete valoarea La transferul parametrilor se efectueaz conversia valori fiecrui parametru efectiv la tipul parametrului formal
CONVERSII DE TIP
Conversii posibile De la tip de baz la tip clas De la tip clas la tip de baz De la tip clas la tip clas Cum se pot realiza?
OPERATORUL DE CAST
Sintax operator tipDeData (); Observaii Operatorul este ntotdeauna funcie membre ale clasei Tipul de return este implicit tipul operatorului Nu are parametrii deoarece primete implicit adresa obiectului curent
class Complex { int re, im; public: operator double(){ return re; } }; void f(){ Complex c(5,6), e(9,3); double d = c; double dd = c + e }
CONVERSII
Suprancrcarea operatorului de cast nu poate realiza conversii dintr-un tip fundamental n tip clas Operatorul de cast este unar Definirea constructorilor nu permite conversia unui tip clas la un tip de baz
TRATAREA EXCEPIILOR
Definiie O excepie este o eroare apare n momentul execuiei unui program (run-time). Exemple Memorie insuficient Un fiier nu poate fi deschis Un obiect invalid pentru o operaie etc
TRATAREA EXCEPIILOR
Ce facem cnd apare o excepie? Terminm programul soluie inacceptabil Returnarea unei valori reprezentative pentru eroare Care ar fi un cod de eroare reprezentativ? Trebuie ca funcia apelant s verifice codul ntors de funcia apelat ntoarce o valoare legal i las programul ntr-o stare ilegal (errno) apelantul trebuie s testeze starea variabilei astfel nct s nu realizeze un apel invalid
Apelarea unei funcii care va trebui apelat n caz de eroare nu exist control asupra codului apelantului
Combinarea codului uzual cu codul de tratare a excepiilor programe greu de citit i ntreinut
TRATAREA EXCEPIILOR
Ce se ntmpl dac nu folosim un mecanism de tratare a excepiilor? Cnd apare o excepie, controlul este predat sistemului de operare, de obicei
Un mesaj de eroare este afiat Programul se termin
ABORDARE
Codul care detecteaz o eroare O propag mai departe throw O trateaz try catch
void operation() { if(daca_un_caz_de_erore_exista) { // arunc un obiect de // tip excepie throw TipExceptie(); } } void f() { try { // cod care ar putea arunca o excepie } catch(TipExceptie1 e1) { // trateaz o excepie de tip1 } catch(TipExceptie2 e2) { // trateaz o excepie de tip2 } }
EXEMPLU
Clasa Stiva
class Stiva{ int *tab; //tablou care contine elementele listei int dim; int index; //indexul elementului curent din lista public: void adauga(int x){ /**functia adauga elementul x in stiva*/ tab[index] = x; index++; } int scoate(){ /**functia scoate un element din stiva*/ return tab[index--];
}
};
EXEMPLU
Exist cazuri cnd pot aprea probleme la funciile Adauga() Scoate()
EXEMPLU
Exist cazuri cnd pot aprea probleme la funciile Adauga() Scoate()
Probleme
Stiva plin Stiva goal Cum rezolvm? Definim o clas se exepii Obs: putem utiliza tipurile de date existente
EXEMPLU. MODIFICARE
class StivaGoala { };
class Stiva{
. void adauga(int x){ /**functia adauga elementul x in stiva*/ if (index ==dim) throw Stiva Plina!; tab[index] = x; index++; } int scoate(){ /**functia scoate un element din stiva*/
if (index ==0)
throw StivaGoala(); return tab[index--]; } };
EXEMPLU. TRATARE
Codul care arunc excepia este ncadrat ntr-un bloc try{}catch{}
int main() { try { Stiva s(1); s.scoate(); s.adauga(4); s.adauga(5); } catch (StivaGoala) { cout << Stiva este goala! <<endl; } catch (char *a) { cout<< Exceptia prinsa: << a << endl; } }
GRUPAREA EXCEPIILOR
Excepiile de obicei sunt grupate n familii se poate folosi motenirea
class MathException { public: virtual string getDescription() { cout << Math ex; } } void f() { try { // using math functions catch(Overflow) { // handle Overflow exceptions } class Overflow : public MathException { public: catch(MathException &e) { // handle any Math exceptions // that is not Overflow cout << e.getDescription(); // call MathException::getDescription } class Underflow : public MathException { }
};
};
GRUPAREA EXCEPIILOR
Observaii Argumentul din cauza de catch nu este obligatoriu Ierarhiile de excepii mresc robusteea abordri Se poate folosi i motenire multipl Este bine s prindem prima dat excepiile de tip subclas i apoi cele de tip supraclas
SPECIFICAREA EXCEPIILOR
Lista se excepii aruncate de o funcie se poate specifica ca parte a declarrii funciilor Sintax Tip nume_functie (lista_argumente) throw (list_de_excepii) Exemplu Void adunare(Marice &m1, Matrice &m2) throw (ExceptieMatematica, alocare_incorecta) Dac lista de excepii lipsete o funcie poate arunca orice excepie Void f() throw(); - nu arunc nici o excepie
SPECIFICAREA EXCEPIILOR
Observaii Specificarea excepiilor trebuie inclus att n declaraia ct i n definiia funciei O funcie virtual poate fi supradefinit doar de o funcie care este cel puin la fel de restrictiv ca funcie iniial Dac o alt excepie este aruncat n afara celor specificate n clauza throw apel std::unexped(), care apeleaz std::terminate() care apeleaz funcie abrout() Se poate supradefini comportamentelor funciilor std::unexped(), std::terminate() prin suprascrierea handlerelor set_unexpected respectiv set_terminate
EXCEPTII NEPRINSE
Dac o excepie este aruncat dar nu este prins, funcia std::terminate va fi apelat Pentru a prinde toate excepiile netratate se poate utiliza urmtorul bloc
int main() { try { // do the actual job } catch() { // handle any uncaught exception so far } }
Aruncarea unei excepii este mai puin costisitoare dect apelul unei funcii STL librria standard a C++ propune o ierarhie de excepii
RE-TRANSMITEREA EXCEPIILOR
Dup ce s-a realizat o corecie a datelor ntr-o clauz catch, excepia poate fi aruncat pentru a fi procesat mai departe
void func() { try{
throw;
} }
CONSTRUCTORI I EXCEPII
Cum se raporteaz erorile n constructor?
}
class Vector { catch(Vector::BadSize& bs) { } cout << Return successfully.; return;
public:
class BadSize { } ; Vector(int sz) { if(sz<0 || sz>MAX_SIZE) throw BadSize(); // codul } };
};
class Map{
public:
Vector val, key; Vector(int sz) try { : val(sz),key(sz){} } catch(Vector::BadSize& bs) {} };
CURS VIITOR
Motenire