Elementi di
programmazione
ad oggetti
a. a. 2009/2010
Corso di Laurea Magistrale in Ingegneria Elettronica
Docente: Mauro Mazzieri, Dipartimento di Ingegneria Informatica,
Gestionale e dell’Automazione
Lezione 8
Gestione delle eccezioni
Fallimenti software

Un sistema software può non essere
in grado di compiere il suo dovere
A causa di errori nella sua
implementazione
 Per l’impossibilità di ottenere risorse
esterne di cui ha bisogno

Non si può rimediare agli errori di
programmazione al momento
dell’esecuzione, salvo cercare di fornire
spiegazioni adeguate all’utente.
Fallimenti dovuti a cause
esterne

Un sistema software può avere
bisogno di risorse da
Hardware
 Sistema operativo
 File system
 Rete
 Database
 Utente


È possibile che tali risorse non siano
disponibili o non siano adeguate
Anomalie ed eccezioni

Le eccezioni sono delle anomalie rilevabili
al momento dell’esecuzione





Divisione per 0
Accesso ad un elemento dell’array oltre i suoi
limiti
Esaurimento della memoria
Dato ricevuto in input di un tipo non atteso
Quando si verifica un evento eccezionale,
la parte di programma che la rileva la può
segnalare sollevando (lanciando)
un’eccezione
Gestione delle eccezioni

La gestione delle eccezioni è un
meccanismo tramite il quale una parte di
un programma può segnalare un problema
che verrà gestito altrove



In una parte di un programma si verifica un
problema che non è in grado di risolvere
In un’altra parte del programma si sa come
gestire il problema
Tramite la gestione delle eccezioni si
trasferisce il controllo della gestione degli
eventi eccezionali

Non è però un meccanismo di controllo come
gli altri
Gestione delle eccezioni

Espressione throw



Blocco try



Segnala la presenza di un’anomalia che non si è
in grado di gestire localmente
L’espressione che segue la parola chiave throw
è il tipo dell’espressione lanciata
Definisce un campo d’azione locale e racchiude
tutte le istruzioni che possono lanciare eccezioni
Un blocco try termina con una o più clausole
catch che catturano e gestiscono le eccezioni
Classi exception

Passano informazioni sull’errore da dove viene
generato a dove viene gestito
Lancio di eccezioni

Un’eccezione si lancia con un’espressione
throw

Parola chiave throw seguita da un’espressione



Alcune eccezioni, ad esempio runtime_exception,
sono definite dalla libreria standard in stdexcept
Generalmente l’operando è un oggetto che
rappresenta l’eccezione
È possibile che venga lanciata un’espressione anche
dal blocco catch


Un’eccezione non è una richiesta di terminazione di
un programma


In questo caso può essere gestita solo da un blocco try
più esterno
Ma un’eccezione non gestita causa la terminazione del
programma
Un throw senza argomenti causa la terminazione
immediata del programma

Salvo il caso di rilancio di un’eccezione
Esempio: lancio di eccezione
Razionale::Razionale(int num,
int den) {
n = num;
if (den == 0)
throw new
runtime_error("il
denominatore non può essere
0");
d = den;
}
Blocco try
try {
// codice che potrebbe lanciare
eccezioni
// es. throw exception;
} catch(E1 ex) {
// codice che gestisce le
eccezioni di tipo E1
} catch(E2 ex) {
// codice che gestisce le
eccezioni di tipo E2
}
Esempio: cattura di
un’eccezione con try/catch
int main() {
try {
Razionale r(2, 0);
// …
} catch(const runtime_error*
e) {
cerr << "Eccezione: " <<
e->what() << endl;
}
return 0;
}
Esempio: blocco try di funzione
int main(int argc, char *argv[])
try {
Razionale r(2, 0);
return 0;
} catch(const runtime_error* e) {
cerr << "Eccezione: " << e>what() << endl;
system("PAUSE");
return -1;
}

L’intero corpo della funzione è contenuto nel blocco try

Separazione più netta tra il codice che implementa
l’elaborazione normale e quello che supporta la gestione delle
eccezioni
Cattura di un’eccezione

I gestori delle eccezioni sono
contenuti nei blocchi catch

catch (tipoEccezione eccezione) { //… }
 Cattura
le eccezioni il cui tipo corrisponde a
tipoEccezione

catch(…)
 Cattura
tutte le eccezioni
 Non conosciamo il tipo dell’eccezione
catturata
 Non ha parametri, non possiamo
referenziare l’oggetto che rappresenta
l’eccezione
Cattura di un’eccezione

I catch sono esaminati uno dopo l’altro
nell’ordine in cui sono scritti


“sovraccarico” dei catch
Un blocco catch corrisponde all’oggetto
lanciato se



Sono dello stesso tipo (corrispondenza esatta)
Il parametro è una classe base public
dell’oggetto lanciato
Il catch è il catch(…)
Gli oggetti const lanciati corrispondono solo a
parametri const
Risollevare un’eccezione

Quando un gestore di un’eccezione
non è in grado di elaborarla, può
rilanciare di nuovo l’eccezione

throw senza argomenti
 un
throw senza argomenti al di fuori di un
blocco catch causa la terminazione
immediata del programma

Un’eccezione risollevata può essere
ricatturata da un blocco try più esterno
Flusso di controllo di un
programma


Se non si verifica alcuna eccezione, il codice del
blocco try viene eseguito fino alla fine ed il
contenuto del blocco catch è ignorato
Se viene lanciata un’eccezione, l’esecuzione delle
istruzioni nel blocco try termina e viene eseguita la
procedura di gestione delle eccezioni

Se esiste un blocco catch per gestire le eccezioni del tipo
opportuno, viene eseguito


Dopo l’esecuzione del blocco catch, l’esecuzione prosegue
dall’istruzione che segue l’ultimo blocco catch
Se non esiste nessun blocco catch in grado di gestire
l’eccezione, l’esecuzione riprende dalla funzione
terminate() (definita dalla libreria standard del C++
nell’header exception), che di default chiama abort
per terminare l’esecuzione del programma
Eccezioni della libreria standard

Header exception


Definisce exception, il tipo più generico di eccezione, indica solo il fatto
che si è verificata un’eccezione
Header stdexcept


exception: il tipo più generale
runtime_error: problema che può essere rilevato solo a runtime




logic_errror: problema che avrebbe essere potuto rilevato prima
dell’esecuzione





domain_error: non esiste un risultato per questo valore dell’argomento
invalid_argument: argomento di tipo non appropriato
lenght_error: tentativo di crearo un oggetto di dimensione superiore alla
massima consentita
out_of_range
Header new


range_error: il risultano è fuori dal range
overflow_error
underflow_error
Definisce bad_alloc, lanciata da new se non riesce ad allocare memoria
Header type_info

Definisce bad_cast
Eccezioni della libreria standard
Exception, bad_alloc, bad_cast hanno
solo un costruttore di default
 Le eccezioni in stdexcept hanno solo
un costruttore che prende una stringa
di caratteri (messaggio di errore)
 Hanno solo il metodo const char*
what()


Restituisce un valore definito dal
compilatore (per le eccezioni con
costruttore di default) o la stringa
passata come argomento al costruttore
Specifica delle eccezioni

Una funzione può specificare quali
eccezioni può sollevare

void int f(int a) throw (E1, E2);
specifica che f() può sollevare solo eccezioni di
tipo E1 e E2

Se f() dovesse sollevare un’eccezione di qualsiasi altro
tipo, verrebbe trasformata in std::unexpected()



Di default chiama std::terminate() che a sua volta
invoca abort()
int g() throw();
specifica che g() non solleverà alcuna eccezione
double h(double x);
può sollevare qualsiasi eccezione
Scarica

Lezione 8