Sunteți pe pagina 1din 7

Ce este o excepție?

n O excepție este o eroare care poate să apară


la rularea unui program.
Tratarea Excepțiilor n Exemple:
¨ încercarea de deschidere a unui fișier ce nu există
¨ depășirea limitelor unui tablou
Mihai Gabroveanu ¨ încercarea de alocare a unui spațiu de memorie
ce depășește dimensiunea heap-ului
¨ etc.

Tratarea Excepțiilor 2

Tratarea excepțiilor în C Tratarea excepțiilor în C


n Afișarea unui mesaj de eroare și continuarea n Testarea valorilor returnate de anumite funcţii, cu privire la
posibilele erori ce au apărut pe parcursul execuției acestora
execuției programului n Exemplu
n Afișarea unui mesaj de eroare și terminarea
if (scanf("%d %d",&n,&m) != 2) {
printf("valori invalide");
exit(1);
programului }
scanf("%d",&n);
float *p= (float *) malloc(sizeof(float));
if (n>MAX) { if (p==NULL){
printf("Depasire valoare maxima"); printf("eroare alocare memorie");
exit(1);
exit(1); }
}

Tratarea Excepțiilor 3 Tratarea Excepțiilor 4


Tratarea excepțiilor în C Exemplu: assert
#include <assert.h> Introduceti n:203
n Utilizând macrodefiniția assert. Sintaxă #include <iostream> Assertion failed: n<MAX, file
#define MAX 100 TestAssert.cpp, line 11
assert(expresie); using namespace std;
int main(){ This application has requested the
¨ Dacă valoarea expresiei este false atunci se oprește int t[MAX]; Runtime to terminate it in an unusual
execuția programului și se afișează un mesaj de eroare int i,n; way.
care indică fișierul și (optional) linia unde este poziționată cout<<”Introduceti n:”; Please contact the application's support
cin>>n; team for more information.
macrodefiniția. assert(n<MAX);
¨ Dacă valoarea expresiei este adevarată atunci execuția for(i=0;i<n;i++){
programului se continuă. }
cin>>t[i];

¨ Avantaj: poate fi inactivată în momentul preprocesării }


adaugând macrodefiniţia:
#define NDEBUG

Tratarea Excepțiilor 5 Tratarea Excepțiilor 6

Exemplu: Clasa Vector Exemplu: Clasa Vector (cont.)


class Vector { void Vector::setElement(int i,float val){
private: if (i >= 0 && i < n){ int Vector::getNrElemente() const { void tratareTerminare (){
float t[MAX]; t[i] = val; return n; cout<<"Terminare program!"<<endl;
int n; } else { } }
public: cerr<<"Index invalid: "<<i<<endl; void Vector::citire(){ Se apelează automat la terminarea
Vector(int n); } int i; int main(){ programului.
int getNrElemente() const; } Se pot trata eventualele erori
cout<<"Dati elementele vectorului:"; int n;
void setElement(int i, float val);
for (i = 0; i < n; i++){ atexit(tratareTerminare);
float getElement(int i) const; float Vector::getElement(int i) const {
void citire(); if (i >= 0 && i < n){
cin >> t[i]; Vector v(2);
void afisare(); return t[i]; } v.setElement(0,4);
}; } else { } v.setElement(3,9);
Vector::Vector(int n){ cerr<<"Index invalid: "<<i<<endl; void Vector::afisare() {
assert(n<=MAX); exit(1); int i; v.afisare();
this->n = n; } for (i = 0; i < n; i++){ getch();
for (int i = 0; i < n; i++){ } cout<<t[i]<<" "; return 0;
this->t[i] = 0; } }
} cout<<endl;
} }

Tratarea Excepțiilor 7 Tratarea Excepțiilor 8


Dezavantajele tratărilor erorilor în C Tratarea excepțiilor în C++
n Secvența de apel al unei funcții ce returnează n C++ are un mecanism avansat de tratare a erorilor,
codul ce tratează erorile fiind decuplat de logica
un cod e eroare trebuie sa fie însoțită de aplicației:
foarte multe if-uri pentru a trata posibilele erori ¨ Inițial
scriem codul care dorim să se execute, apoi separat,
n Dezavantajul major: codul de tratare a erorilor ¨ Se scrie codul ce tratează situațiile neprevazute

devine dependent, cuplat de logica aplicației n O excepție în C++ este de regulă un obiect al unei
clase ce este generat la apariția unei erori și
cuprinde de regulă informații sumare despre cauza
erorii.

Tratarea Excepțiilor 9 Tratarea Excepțiilor 10

Generarea şi prinderea excepţiilor Generarea Excepțiilor: throw

n Mecanismul de tratare a excepţiilor presupune: n Aruncarea (generarea) unei excepții se face


¨ Suspendarea execuţiei funcţiei curente în momentul în cu ajutorul intrucțiunii throw
care s-a detectat o eroare, generarea unei excepţii care
conţine informaţii referitoare la eroare și “aruncarea” n Sintaxa:
(throw) ei către funcția apelantă;
throw [<expresie>];
¨ Reluarea execuţiei programului în altă zonă, prinderea
(catch) excepţiei şi executarea acţiunilor necesare tratării n Exemple:
erorilor. throw out_of_range("Depasire limite");
throw 1;

Tratarea Excepțiilor 11 Tratarea Excepțiilor 12


Generarea Excepțiilor: throw (cont.) Prinderea excepțiilor: try/catch
n Mod de execuție: n Recepționarea (prinderea) unei excepții se face utilizând
blocul de instrucțiuni try/catch
¨ se suspendă execuţia funcţiei curente; n Sintaxa:
try {
¨ se crează un obiect corespunzător valorii expresiei ce // secvență de intrucțiuni ce poate genera excepții
urmează cuvântului cheie throw; } catch (TipExceptie1 ex1){
//tratare excepție de tip TipExceptie1
} catch (TipExceptie2 ex2){
Handlere de tratare
¨ obiectul creat este ‘returnat’ către contextul apelant, chiar a erorilor
//tratare excepție de tip TipExceptie2
dacă el nu corespunde tipului valorii de return a funcţiei. ...
} catch (TipExceptieN exN){
¨ înainte de părăsirea funcției toate obiectele create local //tratare excepție de tip TipExceptieN
} catch (…) {
sunt distruse (se apelează destructorii acestora) //tratare orice alta excepție ce poate aparea
}

Tratarea Excepțiilor 13 Tratarea Excepțiilor 14

Prinderea excepțiilor: try/catch(cont.) Exemplu


class E {
public: int main (){
n Mod de execuție: const char* mesaj; int n;
¨ try marchează începutul unui bloc de instrucțiuni care pot genera };
E(const char* m) : mesaj(m) { } cin>>n;
try{
(arunca) excepții void f(int n){ cout<<"Execut functia f("<<n<<")\n";
switch (n){ f(n);
¨ dacă la execuția unei intrucțiuni este aruncată o excepție atunci se case 1: cout<<"Executie cu succes"<<endl;
abandonează execuția instrucțiunilor din bloc și se încearcă throw 0.5; } catch (double n){
(prinderea) identificarea tipului obiectului aruncat cu unul dintre tipurile cout<<"Intructiune ce nu se va executa"; cerr<<"Tratare eroare de tip double: "<<n;
specificat în ramurile catch: TipExceptie1, TipExceptie2, etc. case 2:
case 3:
} catch (E e){
cerr<<"Tratare eroare de tip E: "<<e.mesaj;
¨ Dacă se identifică o ramură catch pentru care tipul excepției coincide throw E("Eroare n este 2 sau 3"); } catch (...){
se va executa secvența de instrucțiuni pentru tratarea acelui tip de cout<<"Intructiune ce nu se va executa";
case 4: }
cerr<<"Tratare eroare necunoscuta";

excepție throw n; getch();


¨ În cazul în care tipul excepției aruncate nu coincide cu nici unul din } }
tipurile specificate în ramurile catch și există ramura catch(…) atunci se }
cout<<"Terminare funtie f()"<<endl;

vor executa instrucțiunile din acel bloc

Tratarea Excepțiilor 15 Tratarea Excepțiilor 16


Exemplu (cont.) Potrivirea Excepțiilor
OUTPUT:
n La aruncarea unei exceptii, se caută cel mai
n=1
Execut functia f(1)
Tratare eroare de tip double: 0.5 n=1
“apropriat” handler în raport cu ordinea în care
n=3
aceștia apar în cod
Execut functia f(3)
Tratare eroare de tip E: Eroare n este 2 sau 3 n La găsirea unei potriviri, căutarea se opreşte
n=4
Execut functia f(4) n Polimorfismul functionează
Tratare eroare necunoscuta

n=5 n E indicat sa prindem o exceptie prin referinţă, pentru


Execut functia f(5)
Terminare funtie f() a evita apelul constructorului de copiere
Executie cu succes

Tratarea Excepțiilor 17 Tratarea Excepțiilor 18

Specificarea excepțiilor generate Exemplu


n Pentru a specifica faptul că o funcție generează void f(int n) throw (double, E, int){
switch (n){
numai un anumit set de excepții de anumite tipuri case 1:
throw 0.5;
atunci utilizăm următoarea sintaxă: cout<<"Intructiune ce nu se va executa";
case 2:
tipr numeFunctie(lista_parametri) throw (TipE1,TipE2, …, TipEn){ case 3:
throw E("Eroare n este 2 sau 3");
} cout<<"Intructiune ce nu se va executa";
case 4:
n Dacă dorim să specificăm că o funcție nu generează throw n;
}
nicio excepție atunci folosim următoarea sintaxă: }
tipr numeFunctie(lista_parametri) throw (){
}

Tratarea Excepțiilor 19 Tratarea Excepțiilor 20


Excepții netratate Re-aruncarea unei excepții
n Dacă un bloc try/catch nu tratează (prinde) un n Dacă se dorește re-aruncarea unei exceptii prinse către contextul superior
atunci se foloseste clauza throw fără nici un argument.
anumit tip de excepție atunci excepția n De obicei, atunci când nu suntem interesaţi de cauza exceptiei, ci doar
dorim eliberarea resurselor, folosim clauza catch(…) pentru a prinde
respectivă este aruncată către contextul excepția, eliberăm resursele şi apoi o aruncăm mai departe
superior. try{
//instructiuni ce pot genera excepții
n Dacă o excepție nu e tratată de nici un } catch(…){
handler, se va apela funcţia terminate(), care //eliberare resurse
throw;
apelează la rândul său abort() – ieşirea din }
program

Tratarea Excepțiilor 21 Tratarea Excepțiilor 22

Tipuri de excepții predefinite Tipuri de excepții predefinite (cont)


n Din clasa exception sunt derivate două clase, logic_error, pentru
raportarea erorilor detectabile înainte de execuţia programului şi
runtime_error, pentru raportarea erorilor din timpul execuţiei programului.
n Principalele clase derivate din logic_error sunt următoarele:
¨ domain_error – raportează violarea unei precondiţii
¨ invalid_argument – argument invalid pentru o funcţie
¨ length_error – un obiect cu o lungime mai mare decât NPOS (valoarea
maximă reprezentabilă)
¨ out_of_range – în afara domeniului
¨ bad_cast – operaţie dynamic_cast eronată
n Principalele clase derivate din runtime_error sunt următoarele:
¨ range_error – violarea unei postcondiţii
¨ overflow_error – operaţie aritmetică eronată (depăşire)
¨ bad_alloc – eroare de alocare

Tratarea Excepțiilor 23 Tratarea Excepțiilor 24


Exemplu Exemplu (cont.)
class Vector { }
private: int main(){
float t[MAX]; void Vector::setElement(int i, float val) int n;
int n; { Vector v(2);
public: if (i >= 0 && i < n){ v.setElement(0,4);
Vector(int n); t[i] = val; try{
int getNrElemente() const; } else { v.setElement(3,9);
void setElement(int i, float val); throw out_of_range("Depasire } catch (exception &e){
float getElement(int i) const; limite"); cerr<<"Eroare:"<<e.what()<<endl;
void citire(); } }
void afisare(); } v.afisare();
}; float Vector::getElement(int i) const { getch();
if (i >= 0 && i < n) return 0;
Vector::Vector(int n){ return t[i]; }
this->n = n; else
if(n>MAX) throw out_of_range("Depasire limite"); OUTPUT:
throw out_of_range("Depasire } Eroare:Depasire limite
dimensiune maxima"); 4 0
for (int i = 0; i < n; i++){
this->t[i] = 0;
}

Tratarea Excepțiilor 25 Tratarea Excepțiilor 26

Temă
n Implementați clasa Cantar. Un cântar are o capacitate
maximă admisă. Dacă se încearcă cântărirea unui
obiect ce depașește cu maxim 10% greutatea
maximă admisă se va genera excepția
AvertismentDepasireGreutate iar dacă se depășește și
acestă limită se va genera eroarea DepasireGreutate.
n Implementați clasa Stiva implementată sub forma
unui tablou alocat dinamic. Gestionați excepțiile ce
pot apărea.

Tratarea Excepțiilor 27

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