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