Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
appunti3s:gestione_delle_eccezioni [2018/04/25 07:55]
127.0.0.1 external edit
appunti3s:gestione_delle_eccezioni [2018/05/03 22:30]
profpro
Line 1: Line 1:
 +> indice > [[appunti3s:​linguaggio_c]]
 +
 ====== Gestione delle eccezioni ====== ​ ====== Gestione delle eccezioni ====== ​
  
Line 54: Line 56:
 ===== Catch generico =====  ===== Catch generico ===== 
 Alla fine della lista dei gestori //catch()// può essere utile inserire un blocco //catch()// che raccolga tutto quello che non è stato ricevuto dai suoi predecessori. Tale gestore deve avere la seguente sintassi: <​code>​ catch(...) ​ {    // contenuto }</​code> ​ Alla fine della lista dei gestori //catch()// può essere utile inserire un blocco //catch()// che raccolga tutto quello che non è stato ricevuto dai suoi predecessori. Tale gestore deve avere la seguente sintassi: <​code>​ catch(...) ​ {    // contenuto }</​code> ​
-Tuttavia questo sistema rischia di catturare anche eccezioni impreviste. La cosa migliore è far derivare tutte le eccezioni dalla classe base //​std::​exception//​ e usare questa forma <​code>​ catch (std::​exception&​ e) {   //​contenuto } </​code>​. +Tuttavia questo sistema rischia di catturare anche eccezioni impreviste. La cosa migliore è far derivare tutte le eccezioni dalla classe base //std%%::%%exception// e usare questa forma <​code>​ catch (std%%::%%exception&​ e) {   //​contenuto } </​code>​. 
-Questo catch generico è spesso controproducente perché catturano delle eccezioni che potrebbero essere gestite ad un livello più esterno. Esistono delle eccezioni che non sono di stretta competenza della funzione dove si è generata l'​eccezione. Ad esempio, un costruttore fa //new// e viene generata un'​eccezione //​std::​bad_allocate//,​ ma la gestione di questo tipo di eccezione è esterna perché è comune a tutte le funzioni.+Questo catch generico è spesso controproducente perché catturano delle eccezioni che potrebbero essere gestite ad un livello più esterno. Esistono delle eccezioni che non sono di stretta competenza della funzione dove si è generata l'​eccezione. Ad esempio, un costruttore fa //new// e viene generata un'​eccezione //std%%::%%bad_allocate//,​ ma la gestione di questo tipo di eccezione è esterna perché è comune a tutte le funzioni.
  
 Se //throw;// viene usato nel catch generico, allora quel catch generico potrebbe essere inutile. Se //throw;// viene usato nel catch generico, allora quel catch generico potrebbe essere inutile.
Line 67: Line 69:
   * usare namespace //​exception//​ (che è contenuto nel namespace //​std//​)  ​   * usare namespace //​exception//​ (che è contenuto nel namespace //​std//​)  ​
  
-Poiché le eccezioni sono delle classi, tra loro esiste una gerarchia e si possono utilizzare tutti gli strumenti offerti dal polimorfismo:​ la classe base si chiama //​std::​exception//,​ e da essa derivano le seguenti classi:+Poiché le eccezioni sono delle classi, tra loro esiste una gerarchia e si possono utilizzare tutti gli strumenti offerti dal polimorfismo:​ la classe base si chiama //std%%::%%exception//,​ e da essa derivano le seguenti classi:
  
 ^ header^ classe ^ descrizione ^  ^ header^ classe ^ descrizione ^ 
-| <new> | std::​bad_alloc | l'​operatore new fallisce|  +| <new> | std%%::%%bad_alloc | l'​operatore new fallisce|  
-| <​exception>​ | std::​bad_exception | il programmatore non ha rispettato la throw list |  +| <​exception>​ | std%%::%%bad_exception | il programmatore non ha rispettato la throw list |  
-| <​typeinfo>​ | std::​bad_cast | errore nel polimorfismo |   +| <​typeinfo>​ | std%%::%%bad_cast | errore nel polimorfismo |   
-| ??? | std::​logic_error |  ??? | +| ??? | std%%::%%logic_error |  ??? | 
-| ??? | std::​runtime_error |  ??? |+| ??? | std%%::%%runtime_error |  ??? |
  
-la classe //​std::​logic_error//​ è a sua volta una classe base da cui derivano le seguenti classi:+la classe //std%%::%%logic_error//​ è a sua volta una classe base da cui derivano le seguenti classi:
  
 ^ header^ classe ^ descrizione ^  ^ header^ classe ^ descrizione ^ 
-| ??? | std::​domain_error | errore di operazione matematica |  +| ??? | std%%::%%domain_error | errore di operazione matematica |  
-| ??? | std::​invalid_argument | .... |  +| ??? | std%%::%%invalid_argument | .... |  
-| ??? | std::​out_of_range |errore di operazione matematica |  +| ??? | std%%::%%out_of_range |errore di operazione matematica |  
-| ??? | std::​length_error| ​ ... |+| ??? | std%%::%%length_error| ​ ... |
  
-la classe //​std::​runtime_error//​ è a sua volta una classe base da cui derivano le seguenti classi:+la classe //std%%::%%runtime_error//​ è a sua volta una classe base da cui derivano le seguenti classi:
  
 ^ header^ classe ^ descrizione ^  ^ header^ classe ^ descrizione ^ 
-| ??? | std::​range_error | ... |  +| ??? | std%%::%%range_error | ... |  
-| ??? | std::​overflow_error |errore di operazione matematica |  +| ??? | std%%::%%overflow_error |errore di operazione matematica |  
-| ??? | std::​underflow_error |errore di operazione matematica | +| ??? | std%%::%%underflow_error |errore di operazione matematica | 
    
  
Line 95: Line 97:
   - tutti i dati che vengono dall'​esterno del programma devono essere considerati "​sporchi"​ e devono essere "​ripuliti"​ (sanitezed) prima di utilizzarli.   - tutti i dati che vengono dall'​esterno del programma devono essere considerati "​sporchi"​ e devono essere "​ripuliti"​ (sanitezed) prima di utilizzarli.
   - meglio non usare //try// per racchiudere la chiamata di una funzione, ma usare //try// nel corpo della funzione da chiamare (altrimenti catch non riuscirebbe a distruggere gli oggetti creati dalla funzione)   - meglio non usare //try// per racchiudere la chiamata di una funzione, ma usare //try// nel corpo della funzione da chiamare (altrimenti catch non riuscirebbe a distruggere gli oggetti creati dalla funzione)
-  - racchiudere //new// dentro //try// (//​std::​bad_allocate//​)+  - racchiudere //new// dentro //try// (//std%%::%%bad_allocate//​)
   - se un blocco //try// viene dopo un //new//, allora il relativo //catch()// deve eseguire prima di tutto //delete// (in ordine inverso) e poi rilanciare re-throw (vedere definizione n.7)   - se un blocco //try// viene dopo un //new//, allora il relativo //catch()// deve eseguire prima di tutto //delete// (in ordine inverso) e poi rilanciare re-throw (vedere definizione n.7)
   - racchiudere //return oggetto;// dentro //try// perché potrebbe generare eccezione di memoria...??? ​   - racchiudere //return oggetto;// dentro //try// perché potrebbe generare eccezione di memoria...??? ​
  • appunti3s/gestione_delle_eccezioni.txt
  • Last modified: 2018/05/03 22:30
  • by profpro