190 likes | 300 Views
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.
E N D
Elementi di programmazione ad oggettia. 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 • 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 • Blocco try • 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 • In questo caso può essere gestita solo da un blocco try più esterno • Un’eccezione non è una richiesta di terminazione di un programma • 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 • range_error: il risultano è fuori dal range • overflow_error • underflow_error • 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 • 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