vjezbe 05 - izuzeci

24
Objektno programiranje (C++) Objektno programiranje (C++) Sveučilište veučilište u Zagrebu agrebu PMF PMF – Matematički odjel Matematički odjel Vježbe 05 Vježbe 05 – Izuzeci (Exceptions) Izuzeci (Exceptions) Vinko Petričević Vinko Petričević

Upload: dado-maja-arsenin

Post on 22-Oct-2015

36 views

Category:

Documents


4 download

TRANSCRIPT

Page 1: Vjezbe 05 - Izuzeci

Objektno programiranje (C++)Objektno programiranje (C++)

SSveučilišteveučilište uu ZZagrebuagrebu

PMF PMF –– Matematički odjelMatematički odjel

Vježbe 05 Vježbe 05 –– Izuzeci (Exceptions)Izuzeci (Exceptions)

Vinko PetričevićVinko Petričević

Page 2: Vjezbe 05 - Izuzeci

Izuzeci (iznimke)Izuzeci (iznimke)

• Izuzeci (exception) su anomalije koje ne spadaju u područje normalnog djelovanja programa, pojavljuju se u tijeku izvoñenja programa (run-time), te zahtjevaju trenutno reagiranje• npr. potrošena memorija, neočekivan ulaz, dijeljenje s nulom,...

• Ključne riječi za bacanje i rukovanje izuzecima:

Objektno programiranje (C++) – Vježbe 05 – Izuzeci (Exceptions) 2

• Ključne riječi za bacanje i rukovanje izuzecima:• throw

• try

• catch

Page 3: Vjezbe 05 - Izuzeci

IzuzeciIzuzeci

• Ideja: kao što korisniku dajemo sučelje za rad s nekom klasom (npr. stog ima metode push, pop, full, empty i display), tako bismo mu trebali dati i popis izuzetaka (tj. potencijalno opasnih situacija) koje bi se mogle dogoditi. Korisnik je onda taj koji bi trebao reagirati na izuzetke i obraditi ih (npr. push je opasan ako ga pozovemo na punom stogu). Umjesto da ispišemo

Objektno programiranje (C++) – Vježbe 05 – Izuzeci (Exceptions) 3

ako ga pozovemo na punom stogu). Umjesto da ispišemo grešku na cout ili cerr i prekinemo izvoñenje programa, pomoću izuzetaka možemo javiti korisniku klase o kakvoj se grešci radi, te omogućiti mu da on na nju reagira po svom nahoñenju.

Page 4: Vjezbe 05 - Izuzeci

Bacanje izuzetkaBacanje izuzetka

• Polazni primjer:• class iStack {

public:iStack( int capacity ) : _stack( capacity ), _top( 0 ) { }bool pop( int &top_value );bool push( int value );

bool full();

Objektno programiranje (C++) – Vježbe 05 – Izuzeci (Exceptions) 4

bool full();bool empty();void display();

int size();

private:int _top;vector< int > _stack;

};

Page 5: Vjezbe 05 - Izuzeci

Bacanje izuzetkaBacanje izuzetka

• Modifikacija primjera:• // stackExcp.h

class popOnEmpty { /* ... */ };class pushOnFull { /* ... */ };

• class iStack {public:

// ...

Objektno programiranje (C++) – Vježbe 05 – Izuzeci (Exceptions) 5

// ...

// funkcije vise ne vracaju vrijednostvoid pop( int &value );void push( int value );

private:// ...

};

Page 6: Vjezbe 05 - Izuzeci

Bacanje izuzetkaBacanje izuzetka

• Modifikacija primjera:• #include "stackExcp.h"

void iStack::pop( int &top_value ) {if ( empty() )

throw popOnEmpty();

top_value = _stack[ --_top ];cout << "iStack::pop(): " << top_value << endl;

Objektno programiranje (C++) – Vježbe 05 – Izuzeci (Exceptions) 6

cout << "iStack::pop(): " << top_value << endl;}

• void iStack::push( int value ) {cout << "iStack::push( " << value << " )\n";

if ( full() )throw pushOnFull();

_stack[ _top++ ] = value;}

Page 7: Vjezbe 05 - Izuzeci

Bacanje izuzetkaBacanje izuzetka

• throw izrazi mogu bacati objekte bilo kojeg tipa• Primjer:

enum EHstate { noErr, zeroOp, negativeOp, severeError };

int mathFunc( int i ) {

Objektno programiranje (C++) – Vježbe 05 – Izuzeci (Exceptions) 7

int mathFunc( int i ) {if ( i == 0 )

throw zeroOp; // izuzetak tipa enum

// nastavak normalnog procesiranja}

Page 8: Vjezbe 05 - Izuzeci

try bloktry blok

• Polazni primjer:• #include <iostream>

#include "iStack.h"

int main() {iStack stack( 16 );stack.display();for ( int ix = 1; ix < 21; ++ix ) {

if ( ix % 3 == 0 )

Objektno programiranje (C++) – Vježbe 05 – Izuzeci (Exceptions) 8

if ( ix % 3 == 0 )stack.push( ix );

if ( ix % 4 == 0 )stack.display();

if ( ix % 10 == 0) {int dummy;stack.pop( dummy );stack.display();

}}return 0;

}

Page 9: Vjezbe 05 - Izuzeci

try bloktry blok

• Modifikacija primjera (1. varijanta):• try {

for ( int ix = 1; ix < 21; ++ix ) {if ( ix % 3 == 0 )

stack.push( ix );if ( ix % 4 == 0 )

stack.display();if ( ix % 10 == 0 ) {

Objektno programiranje (C++) – Vježbe 05 – Izuzeci (Exceptions) 9

if ( ix % 10 == 0 ) {int dummy;stack.pop( dummy );stack.display();

}}

}catch ( pushOnFull ) { ... }catch ( popOnEmpty ) { ... }

Page 10: Vjezbe 05 - Izuzeci

try bloktry blok

• Modifikacija primjera (2. varijanta):• int main() {

try {iStack stack( 16 ); // ok: deklaracija u try blokustack.display();for ( int ix = 1; ix < 21; ++ix ) {

// isto kao ranije}

Objektno programiranje (C++) – Vježbe 05 – Izuzeci (Exceptions) 10

}}catch ( pushOnFull ) {

// ovdje vise ne mozemo referirati stack}catch ( popOnEmpty ) {

// ovdje vise ne mozemo referirati stack}// ovdje vise ne mozemo referirati stackreturn 0;

}

Page 11: Vjezbe 05 - Izuzeci

try bloktry blok

• Modifikacija primjera (3. varijanta):• int main()

try {iStack stack( 16 );stack.display();for ( int ix = 1; ix < 21; ++ix ) {

// isto kao ranije}

Objektno programiranje (C++) – Vježbe 05 – Izuzeci (Exceptions) 11

}return 0;

}catch ( pushOnFull ) {

// ovdje vise ne mozemo referirati stack}catch ( popOnEmpty ) {

// ovdje vise ne mozemo referirati stack}

Page 12: Vjezbe 05 - Izuzeci

Hvatanje izuzetakaHvatanje izuzetaka

• Primjer:• int main() {

iStack stack( 16 );try {

stack.display();for ( int ix = 1; ix < 21; ++ix ) {

// isto kao ranije}

Objektno programiranje (C++) – Vježbe 05 – Izuzeci (Exceptions) 12

}}catch ( pushOnFull ) {

cerr << "trying to push a value on a full stack\n";}catch ( popOnEmpty ) {

cerr << "trying to pop a value on an empty stack\n";}// izvršavanje programa nastavlja se ovdjereturn 0;

}

Page 13: Vjezbe 05 - Izuzeci

Hvatanje izuzetakaHvatanje izuzetaka

• Primjer:• class pushOnFull {

public:pushOnFull( int i ) : _value( i ) { }int value() { return _value; }

private:int _value;

};

Objektno programiranje (C++) – Vježbe 05 – Izuzeci (Exceptions) 13

};• void iStack::push( int value ) {

if ( full() )// value se sprema u iznimcithrow pushOnFull( value );

// ...}

• catch ( pushOnFull eObj ) {cerr << "trying to push the value " << eObj.value()

<< " on a full stack\n";}

Page 14: Vjezbe 05 - Izuzeci

Hvatanje izuzetakaHvatanje izuzetaka

• Primjer:• enum EHstate { noErr, zeroOp, negativeOp, severeError };

enum EHstate state = noErr; int mathFunc( int i ) {

if ( i == 0 ) {state = zeroOp;throw state;

}

Objektno programiranje (C++) – Vježbe 05 – Izuzeci (Exceptions) 14

}// ...

}• void calculate( int op ) {

try {mathFunc( op );

}catch ( EHstate& eObj ) {

eObj = noErr; // globalna varijabla state ovime se ne modificira

}}

Page 15: Vjezbe 05 - Izuzeci

Ponovno bacanje izuzetkaPonovno bacanje izuzetka

• Sintaktički oblik:• throw;

• Primjer:• catch ( exception eObj ) {

if ( canHandle( eObj ) )// baratanje izuzetkom

Objektno programiranje (C++) – Vježbe 05 – Izuzeci (Exceptions) 15

// baratanje izuzetkomreturn;

else// ponovno bacanje istog izuzetka (rethrow)throw;

}

Page 16: Vjezbe 05 - Izuzeci

Hvatanje svih izuzetakaHvatanje svih izuzetaka

• Polazni primjer:• void manip() {

resource res;res.lock(); // zakljucavanje resursa

// koristenje resursa

Objektno programiranje (C++) – Vježbe 05 – Izuzeci (Exceptions) 16

// koristenje resursa// neka akcija koja uzrokuje bacanje izuzetka

res.release(); // ako je bacen izuzetak ovo senece izvrsiti}

Page 17: Vjezbe 05 - Izuzeci

Hvatanje svih izuzetakaHvatanje svih izuzetaka

• Primjer:• void manip() {

resource res;res.lock();try {

// koristenje resursa res// neka akcija moze uzrokovati bacanje izuzetka

}

Objektno programiranje (C++) – Vježbe 05 – Izuzeci (Exceptions) 17

}catch (...) { // ovime hvatamo sve izuzetke

res.release();throw; // proslijedimo izuzetak dalje

}res.release(); // ako je bacen izuzetak ovo se nece

izvrsiti}

Page 18: Vjezbe 05 - Izuzeci

Hvatanje svih izuzetakaHvatanje svih izuzetaka

• Primjer:• try {

stack.display();for ( int ix = 1; ix < 21; ++ix ){

// isto kao ranije

Objektno programiranje (C++) – Vježbe 05 – Izuzeci (Exceptions) 18

// isto kao ranije}

}catch ( pushOnFull ) { }catch ( popOnEmpty ) { }catch (...) { } // posljednja catch klauzula

Page 19: Vjezbe 05 - Izuzeci

Specifikacija izuzetakaSpecifikacija izuzetaka

• Primjer:• class iStack {

public:// ...

void pop( int &value ) throw(popOnEmpty);

Objektno programiranje (C++) – Vježbe 05 – Izuzeci (Exceptions) 19

void pop( int &value ) throw(popOnEmpty);void push( int value ) throw(pushOnFull);

private:// ...

};

Page 20: Vjezbe 05 - Izuzeci

IzuzeciIzuzeci

• Primjer: new ne vraća NULL pokazivač ako nije uspio alocirati memoriju, nego baca iznimku.

• Zadatak: Napišite program koji alocira 100kB memorije i ispisuje pointer na rezervirani blok.

• Zadatak: Napišite program koji alocira 1GB memorije i ispisuje

Objektno programiranje (C++) – Vježbe 05 – Izuzeci (Exceptions) 20

• Zadatak: Napišite program koji alocira 1GB memorije i ispisuje pointer koji je dobio. Što se dogodilo?

• Zadatak: Napišite program koji alocira 1GB i hvata iznimku koju je bacio new.

Page 21: Vjezbe 05 - Izuzeci

IzuzeciIzuzeci

• Standardne biblioteke za rad sa izuzecima:• #include <stdexcept>

• exception

• runtime_error

• range_error

Objektno programiranje (C++) – Vježbe 05 – Izuzeci (Exceptions) 21

• range_error

• overflow_error

• itd.• #include <exception>

• #include <new>

• #include <type_info>

Page 22: Vjezbe 05 - Izuzeci

IzuzeciIzuzeci

• Zadatak: Bitset operacija to_ulong baca overflow_error iznimku ako je bitset prevelik za veličinu unsigned long. Napišite program koji generira i obrañuje navedenu iznimku.

• Zadatak: napišite program koji učitava dva broja koja treba podijeliti. Pogledajte što se dogaña ako dijelite s nulom.

Objektno programiranje (C++) – Vježbe 05 – Izuzeci (Exceptions) 22

podijeliti. Pogledajte što se dogaña ako dijelite s nulom. Prepravite program tako da baci grešku Dijeljenje_s_nulom(), te uhvatite i obradite navedenu iznimku.

Page 23: Vjezbe 05 - Izuzeci

try blok i kontrola kopiranjatry blok i kontrola kopiranja

• Prilikom bacanja iznimke, prvo se kreira klasa koja se šalje kao iznimka

• nakon toga unište se sve varijable kreirane od odgovarajučeg try bloka

• ako je u catch bloku klasa navedena bez reference, desit će se

Objektno programiranje (C++) – Vježbe 05 – Izuzeci (Exceptions) 23

• ako je u catch bloku klasa navedena bez reference, desit će se njezin copy-konstruktor

• pa ipak, desi li se throw tijekom izvršavanja nekog destruktora, u VS ga nećemo moći uhvatiti, te će nam se program srušiti

Page 24: Vjezbe 05 - Izuzeci

try blok i kontrola kopiranjatry blok i kontrola kopiranja• struct Ex {{{{

Ex()()()() {{{{ cout<<"kreiran Ex "<<this<<<<"kreiran Ex "<<this<<<<"kreiran Ex "<<this<<<<"kreiran Ex "<<this<<endl;};};};}Ex(const(const(const(const Ex&&&& e)))) {{{{ cout<<"kopiran Ex "<<this<<"kopiran Ex "<<this<<"kopiran Ex "<<this<<"kopiran Ex "<<this

<<" <<<" <<<" <<<" <---- "<<&"<<&"<<&"<<&e<<<<<<<<endl;};};};}~~~~Ex()()()() {{{{ cout<<"unisten Ex "<<this<<<<"unisten Ex "<<this<<<<"unisten Ex "<<this<<<<"unisten Ex "<<this<<endl;};};};}

};};};};• struct S {{{{

S()()()() {{{{ cout<<"kreiran S "<<this<<<<"kreiran S "<<this<<<<"kreiran S "<<this<<<<"kreiran S "<<this<<endl;};};};}S(const(const(const(const S&&&& e)))) {{{{ cout<<"kopiran S “<<"kopiran S “<<"kopiran S “<<"kopiran S “

<<this<<" <<<this<<" <<<this<<" <<<this<<" <---- "<<&"<<&"<<&"<<&e<<<<<<<<endl;};};};}~~~~S()()()() {{{{ cout<<"unisten S "<<this<<<<"unisten S "<<this<<<<"unisten S "<<this<<<<"unisten S "<<this<<endl;};};};}

};};};};

Objektno programiranje (C++) – Vježbe 05 – Izuzeci (Exceptions) 24

};};};};

• int main()()()() {{{{try {{{{

S s;;;;cout<<"program ide"<<<<"program ide"<<<<"program ide"<<<<"program ide"<<endl;;;;throw Ex();();();();

}}}}catch ((((Ex e)))) {{{{

cout<<"hvatanje greske"<<<<"hvatanje greske"<<<<"hvatanje greske"<<<<"hvatanje greske"<<endl;;;;}}}}return 0;0;0;0;

}}}}

kreiran S 0012FF53kreiran S 0012FF53kreiran S 0012FF53kreiran S 0012FF53program ideprogram ideprogram ideprogram idekreiran Ex 0012FE7Bkreiran Ex 0012FE7Bkreiran Ex 0012FE7Bkreiran Ex 0012FE7Bkopiran Ex 0012FF47 <kopiran Ex 0012FF47 <kopiran Ex 0012FF47 <kopiran Ex 0012FF47 <---- 0012FE7B0012FE7B0012FE7B0012FE7Bunisten S 0012FF53unisten S 0012FF53unisten S 0012FF53unisten S 0012FF53hvatanje greskehvatanje greskehvatanje greskehvatanje greskeunisten Ex 0012FF47unisten Ex 0012FF47unisten Ex 0012FF47unisten Ex 0012FF47unisten Ex 0012FE7Bunisten Ex 0012FE7Bunisten Ex 0012FE7Bunisten Ex 0012FE7B