Presentation is loading. Please wait.

Presentation is loading. Please wait.

Iznimke C++ nudi mehanizam izbacivanja i hvatanja iznimaka za postupanje s greškama pri izvršavanju programa. Uporaba tog mehanizma nije nužna jer se.

Similar presentations


Presentation on theme: "Iznimke C++ nudi mehanizam izbacivanja i hvatanja iznimaka za postupanje s greškama pri izvršavanju programa. Uporaba tog mehanizma nije nužna jer se."— Presentation transcript:

1 Iznimke C++ nudi mehanizam izbacivanja i hvatanja iznimaka za postupanje s greškama pri izvršavanju programa. Uporaba tog mehanizma nije nužna jer se greške mogu tretirati na tradicionalan način, ali on nudi važnu mogućnost separacije koda koji reagira na grešku od koda u kojem je došlo do greške. To je važno u onim situacijama kada na grešku nije moguće adekvatno reagirati tamo gdje se pojavila.

2 Iznimke Dio programa koji može izbaciti izuzetak zatvori se u try blok. Njega slijede jedan ili više catch blokova koji hvataju i procesuiraju izuzetak. Izuzetak se izbacuje pomoću throw naredbe. Izvršavanje programa se zaustavlja u liniji koda u kojoj je izbačen izuzetak i počinje potraga za prvim catch blokom koji deklarira izbačeni izuzetak. Ako je takav blok nađen, program se nastavlja u njemu. Ako u try bloku nije izbačen izuzetak, pripadni catch blokovi se preskaču i program se nastavlja iz njih. Ako je izuzetak izbačen, ali nije nađen catch blok koji ga deklarira (premda može biti drugih catch blokova) potraga za catch blokom se nastavlja u pozivnom programu, rekurzivno, sve dok se ne nađe. Ako nije nađen niti u main funkciji, program će biti zaustavljen.

3 Iznimke Try-catch blok oblika try { f(); } catch (tipIznimke &e) {
…….      } mogao bi se realizirati i pomoću if-else uvjeta (od funkcije očekujemo da vraća povratnu vrijednost pomoću koje možemo kontrolirati greške). Npr. možemo pisati:

4 Iznimke int r = f( ); if (!r) { ... } else { . }
gdje funkcija f vraća nulu ako nije došlo do pogreške, odnosno neku nenul vrijednost u slučaju pogreške.

5 Iznimke Takav način tretiranja pogrešaka je vrlo nepraktičan, posebno ako poziv funkcije f uključuje dodatne pozive funkcija. Sljedeći kod     try {    …  f( );    …    }  catch (tipIznimke& e) { … }         void f( )  {  … f1( );  … }  void f1( ) { …  f2( );  …  }  …….. void f6( )  { …   f7( );  …  }    void f7( )  {    …      throw iznimka;     … } bi bez try-catch bloka mogao izgledati ovako:

6 Iznimke int f(){ …… int r=f1(); if (!r) { …… } ……. else { …. }
return 0; } int f1(){ …. int r=f2(); if (r) return 1; …… ………. int f7(){ ….. if (pogreška) return 1; …..

7 Iznimke int main(){ throw 1000; // throw izvan try bloka, nema catch bloka koji može uhvatiti iznimku try { throw 1000; } catch ( int e ){ cout<< " Uhvacena int iznimka. "; return 0;

8 Iznimke int main(){ try{ throw 1; throw 2; // ne izvršava se }
catch (int e) { cout<<"Uhvatio"<<e; return 0;

9 Iznimke int main(){ try{ int a=2; throw a; } catch (int e){
cout<<"Izbacen je "<<a; // varijabla više ne postoji cout<<"Uhvacen je "<<e; return 0;

10 Iznimke #include <vector> #include <iostream> int main() {
   std::vector<double> v(2,1.0); // vektor od dva elementa inicijalizirana s 1.0      std::cout << v.at(3) << std::endl; // izbacuje izuzetak std::out_of_range      return 0; }

11 Iznimke #include <vector> #include <iostream>
void f(int i, std::vector<double>& v) {     std::cout << v.at(i) << std::endl; // izbacuje izuzetak ovisno o indeksu i      throw 1000; // izbacuje izuzetak      v[i] = 3.14; // nikad neće biti izvršeno } int main() {      std::vector<double> v(2,1.0);      int i;      std::cin >> i;      try{    f(i,v);  }      catch(int e)     {          std::cout << "Uhvatio cjelobrojni izuzetak." << std::endl;      }      std::cout << "Zavrsio." << std::endl;      return 0;

12 Iznimke #include <vector> #include <iostream>
#include <stdexcept> int main() {      std::vector<double> v(2,1.0);      int i;      std::cin >> i;      try{         f(i,v);     }      catch(int e)     {          std::cout << "Uhvatio cjelobrojni izuzetak." <<std::endl;      }      catch(std::out_of_range e)     {            std::cout << "Uhvatio out_of_range izuzetak." << std::endl;            std::cout << e.what() << std::endl;      }      std::cout << "Zavrsio." << std::endl;      return 0; }

13 Iznimke int main( ){ try{ throw 1; } catch (string e){
cout<<"Uhvacen je string"; catch(...) { // ovaj blok hvata bilo koju iznimku cout<<"Uhvacena je neka iznimka"; return 0;

14 Iznimke Standardne iznimke: exception runtime_error range_error
overflow_error underflow_error logic_error domain_error invalid_argument length_error. bad_alloc bad_cast Sve ove klase nude metodu what koja vraća string koji opisuje izuzetak.

15 Iznimke class exception { public: exception(); exception(const char * const &message); exception(const char * const &message, int); exception(const exception &right); exception& operator=(const exception &right); virtual ~exception(); virtual const char *what() const; };

16 Iznimke class logic_error : public exception { public:
explicit logic_error(const string& message); virtual const char *what(); }; class runtime_error : public exception { explicit runtime_error(const string& message);

17 Iznimke Sljedeće klase su izvedene iz klase logic_error: domain_error
invalid_argument length_error out_of_range Iz klase runtime_error su izvedene: overflow_error range_error underflow_error

18 Iznimke void f(){ try { throw std::string("u funkciji f"); }
catch(int e) { std::cout<<"Uhvatio int iznimku - u funkciji f"; } } int main() { try f(); catch(int e) std::cout<<"Uhvatio sam int iznimku – u funkciji main"; catch(std::string e) std::cout<<"Uhvatio sam string iznimku";

19 Iznimke void f(){ try { throw 1000; }
catch(int e) { std::cout<<"Uhvatio int iznimku - u funkciji f"; } } int main() { try f(); catch(int e) std::cout<<"Uhvatio sam int iznimku – u funkciji main"; catch(std::string e) std::cout<<"Uhvatio sam string iznimku";

20 Iznimke Funkcijski try-catch blok
#include <iostream> #include <stdexcept> using namespace std; void f(int i) try{ if (i<3) throw out_of_range ("Broj treba biti veci od 2."); cout<<i<<endl; } catch(out_of_range e) { std::cout<<e.what()<<endl; int main() { f(2); f(3); return 0; Funkcijski try-catch blok

21 Iznimke Catch blok koji obrađuje iznimku je prvi u nizu pripadnih catch blokova koji može primiti tip iznimke. Pritom nisu dopuštene sve konverzije koje su dopuštene pri prosljeđivanju argumenata funkcijama. Dozvoljene su sljedeće: Konverzija iz nekonstantnog objekta u konstantan je dozvoljena. Specijalno, izbacivanje nonconst objekta se slaže s catch blokom koji prima const referencu. Konverzija iz izvedenog u bazni tip je dozvoljena (detalji kasnije). Polja i funkcije se konvertiraju u odgovarajuće pokazivače. Najspecijaliziraniji catch blok bi trebao biti prvi u nizu.

22 Iznimke int main() { try{ int a=2; throw a; } catch (const double& ){cout<<"Uhvatio double"; } catch (const int& ){cout<<"Uhvatio int"; } // ovaj catch hvata iznimku return 0;

23 Iznimke void f(string s) { std::cout<<"U funkciji sam f"; } int main() try f("Tekst"); // konverzija kod funkcije radi throw "Tekst"; catch(string) { std::cout<<"Uhvatio sam string"; } catch(exception) { std::cout<<"Uhvatio sam objekt tipa exception"; } // nema catch bloka koji bi uhvatio iznimku return 0;

24 Iznimke void f(string s) { std::cout<<"U funkciji sam f"; } int main() try f("Tekst"); string s(“Tekst”); throw s; catch(string) { std::cout<<"Uhvatio sam string"; } // ovaj catch sad može uhvatiti iznimku catch(exception) { std::cout<<"Uhvatio sam exception"; } return 0;

25 Iznimke void f( int & i ) { cout<<"f( int & )"; }
void f(const int & i) { cout<<"f( int & )"; } // ove funkcije mogu koegzistirati int main( ) { int a=2; f(a); // f(int &) return 0; }

26 Iznimke void f( int & i ) { cout<<"f( int & )"; }
void f(const int & i) { cout<<"f( int & )"; } int main( ) { int a=2; f(a); try{ throw a; } catch (const int & e){ cout<<"Uhvatio "<<e<<" preko const reference"; catch (int & e){ cout<<"Uhvatio "<<e<<" preko nonconst reference"; return 0;

27 Iznimke void f( int & i ) { cout<<"f( int & )"; }
void f(const int & i) { cout<<"f( int & )"; } int main( ) { int a=2; f(a); try{ throw a; } catch (const int & e){ cout<<"Uhvatio "<<e<<" preko const reference"; catch (int & e){ cout<<"Uhvatio "<<e<<" preko nonconst reference"; // treba izbaciti jedan od catch blokova return 0;

28 Iznimke void f( ); void f1( ); void f2( ); void f3( ); void f( ) { f1( ); } void f1( ) { try { f2( ); } catch (const char * e) { cout<<"f1"; } } void f2( ) { try { f3 ( ); } catch (string e) { cout<<"f2" ; } } void f3( ) { throw "Iznimka"; } int main( ) { try { f( ); } catch (const char * e) { cout<<"main"; } // ispisuje f1 return 0; }

29 Iznimke Ponekad catch blok koji je uhvatio iznimku nije u mogućnosti u potpunosti obraditi tu iznimku, već samo djelomično. Stoga, taj catch blok može ponovo izbaciti uhvaćenu iznimku koju može uhvatiti neki od odgovarajućih catch blokova koji se u lancu pripadnih funkcijskih poziva nalazi iznad trenutnog catch bloka. Ponovno izbacivanje iznimke postiže se opet pomoću ključne riječi throw, ali ovaj put bez navođenja objekta, odnosno izraza: throw;

30 Iznimke void f( ); void f1( ); void f2( ); void f3( );
void f( ) { f1( ); } void f1( ) { try { f2( ); } catch (const char * e) { cout<<"f1 "; throw; } } void f2( ) { try { f3 ( ); } catch (string e) { cout<<"f2 " ; } } void f3( ) { throw "Iznimka"; } int main( ) { try { f( ); } catch (const char * e) { cout<<"main"; } cout<<“Sve u redu”; // f1 main return 0; }

31 Iznimke Objekt koji se time izbacuje je originalan objekt koji je uhvaćen, a ne catch parametar. Dakle, objekt kojeg izbacuje catch blok se može razlikovati od objekta kojeg je taj catch blok uhvatio jedino ako je hvatanje objekta izvršeno po referenci i ako je catch blok prethodno mijenjao taj objekt.

32 Iznimke void f1( ); void f( ){ try{ f1( ); }
catch(int &e){ ++e; throw; } } void f1( ) { try { throw 1; } catch (int e){ ++e; throw; } int main(){ try{ f(); } catch(int e){ cout<<"Uhvacen je broj"<<e; } return 0;

33 Iznimke void f1( ); void f( ){ try{ f1( ); }
catch(int &e){ ++e; throw; } i // izbacuje 2 } void f1( ) { try { throw 1; } catch (int e){ ++e; throw; } // izbacuje 1 int main(){ try{ f(); } catch(int e){ cout<<"Uhvacen je broj"<<e; } return 0;

34 Iznimke void f1( ); void f( ){ try{ f1( ); }
catch(int &e){ ++e; throw e; } } void f1( ) { try { throw 1; } catch (int e){ ++e; throw e; } int main(){ try{ f(); } catch(int e){ cout<<"Uhvacen je broj"<<e; } return 0;

35 Iznimke void f1( ); void f( ){ try{ f1( ); }
catch(int &e){ ++e; throw e; } // izbacuje 3 } void f1( ) { try { throw 1; } catch (int e){ ++e; throw e; } // izbacuje 2 int main(){ try{ f(); } catch(int e){ cout<<"Uhvacen je broj"<<e; } return 0;


Download ppt "Iznimke C++ nudi mehanizam izbacivanja i hvatanja iznimaka za postupanje s greškama pri izvršavanju programa. Uporaba tog mehanizma nije nužna jer se."

Similar presentations


Ads by Google