feed
top
crea forum
cerca
feed
forum
supporto
discussione
cerca
JEHOVA e la NUOVA GERUSALEMME > INIZIO <
Blog libero tutti possono commentare nella zona chiacchiere tutti possono dire la sua , la CHAT è libera tutti possono usarla
Cerca
INDICE Appunti sulla programmazione C++
Accedi
13) Le eccezioni per il controllo degli errori di programma try catch e throw
Messaggi
OFF
LINE
JehovaZorobabele
Post: 257
Post: 246
Registrato il: 02/03/2016
Registrato il: 03/03/2016
Sesso: Maschile
0
0
27/08/2016
00:16
Gestione degli errori controllati da try throw catch e altre funzioni che fa parte dell' header
La parola
try
già l’ abbiamo usata nel capitolo 9 dentro il testo Pdf, oppure dentro il forum con il messaggio 9 , ora vedremo meglio di che cosa si tratta intanto la sintassi è:
try { blocco try}
catch(tipo1 argomenti ) {blocco catch} catch(tipo2 argomenti) {blocco catch} ecc… catch(tipoX argomenti ) { blocco catch}
La vera eccezione la lancia
throw eccezione ;
dove possiamo dire che è uguale all’ istruzione
return
di una funzione dove ci restituisce un risultato, invece
throw
ci restituisce un errore , infatti per eccezioni si intende un errore, oppure
throw
è simile alla istruzione
goto
perché ci manda verso la funzione
catch,
cosi salta tutto quello che arriva dopo l’ eccezione, nel caso che l’ errore non è intercettato il programma segue il normale flusso, l’ eccezione è un tipo di dato che può essere int, char double , l’ eccezione di
throw
viene poi gestita o catturata da
catch (tipo_gestione ) { descrizione tipo errore }
throw
deve essere eseguita dentro un blocco
try
questo viene fatto con chiamata diretta oppure indiretta tramite funzioni , l’ importante che sia prima del relativo
catch
che tradotto vuol dire proprio cattura, mentre
throw
vuol dire getta o gettare mentre try la troviamo anche come processare oppure verificare ecc….
L’ eccezione possiamo gestirla da dentro il main oppure da dentro una funzione vediamo un uso dentro il
main()
quando chiamiamo la funzione catch la variabile che uso
ER
non è importante, ma serve a noi per leggere il tipo errore, ma è importante il tipo di dato emesso da
throw
che nel nostro caso è double se nella funzione
catch
inserite
int
anzi che double il compilatore VS2015 da errori e esce una finestra per le eccezioni di errore vedete l’istruzione
cout
quella non verrà mai eseguita finche’ c’è l’ istruzione
throw
ecco il programma anzi che usare
cout uso cerr
che serve proprio per la gestione degli errori cerr si usa uguale a cout :
#include<iostream> using namespace std; int main() { cout << " inizio delle eccezioni \n";
try {
cerr << "\n Qui siamo dentro il blocco try e lanciamo una eccezione di tipo\n double 10.2 ora il programma trova l'istruzione [ throw 10.2 ] ";
throw 10.2;
cerr << " NUOVA ISTRUZIONE che viene saltata ";
}
catch (double ER)
{ cerr << "\n con [ catch (double ER) ], (double ER) raccoglie il tipo\n di errore lanciato da throw, ER e'usato come variabile \n"; cerr << " Abbiamo raccolto l'errore numero ER: " <<
ER
<< endl; cerr << "\n Puo seguire altre istruzioni sul tipo di errore\n e come risolvere il problema.\n"; }
cout << "\n Per USCIRE usiamo [ system (\"pause\") ] con i comandi di try\n si esce direttamente come se ci fosse un exit(1) \n "; system("pause"); }
Effettivamente se si toglie
throw
, basta mettere come se fosse un commento, vedete cambia tutto il risultato troviamo la
NUOVA ISTRUZIONE
e subito dopo l’ istruzioni per l’ uscita, ora non c’è traccia di
catch
e delle sue istruzioni.
Ora lo stesso programma ma
try throw e catch
tutto dentro una funzione tER è tipo_errore , se abbiamo la condizione tra
if (tER) throw tER;
con le chiamate delle funzioni
funzione(3); funzione(5.1); funzione(0); funzione('z');
tutte sono chiamate eccetto la
funzione (0);
, per
funzione(‘z’);
abbiamo il numero 122 che corrisponde al carattere z se cambiate il carattere cambia anche il numero anche tra caratteri maiuscoli e minuscoli per far funzionare il mio programma copiato o incollato ricordate di spostare
using namespace std;
sotto l’
#include
:
#include<iostream> using namespace std;
void funzione (int tER)
{ try
{ cerr << "\n Qui siamo dentro il blocco try dentro la funzione ora\n lanciamo una eccezione di tipo tER ora il programma \n trova (tipo ERRORE = tER )tramite l'istruzioni \n [ if(tER) throw tER ] ";
if (tER) throw tER;
}
catch (int ER)
{ cerr << "\n con [ catch (double ER) ], (double ER) raccoglie il tipo\n di errore lanciato da throw, ER e'usato come variabile \n"; cerr << " Abbiamo raccolto l'errore numero ER: " << ER << endl;
cerr << "\n (Puo seguire altre istruzioni sul tipo di errore\n e come risolvere il problema.) \n"; } }
int main() { cerr << " inizio delle eccezioni \n";
funzione(3); funzione(5.1); funzione(0); funzione('z');
cout << "\n Per USCIRE usiamo [ system (\"pause\") ] con i comandi di try\n si esce direttamente come se ci fosse un exit(1) \n "; system("pause"); }
Come si vede dal risultato ogni volta che la funzione è chiamata viene inizializzata, poi secondo il confronto viene scritta o meno l’ istruzioni seguenti all’ if, con la
funzione 0
la parte di
catch
non viene eseguita
Possiamo utilizzare più istruzioni catch legate ad un comando
try
anche qui si deve avere un tipo di overload ovvero non possono essere uguali ad esempio possiamo vedere un
throw
che lavora su diversi tipi pertanto dobbiamo raccogliere diversi tipi di errori sviluppiamo il nuovo programma che grosso modo è simile a quello già sviluppato in precedenza ovvero viene inserito poche differenze vedete tutto quello racchiuso dentro le righe è la nuova modifica che è segnato con il
marcatore
tutto il resto rimane come prima, l’ errore lo genera il comando della
funzione (0);
:
#include<iostream> using namespace std;
void funzione (int tER)
{ try { cerr << "\n Qui siamo dentro il blocco try dentro la funzione ora\n lanciamo una eccezione di tipo tER ora il programma \n trova (tipo ERRORE = tER )tramite l'istruzioni \n [ if(tER) throw tER ] ";
if (tER) throw tER;
else throw "\n[ NEW ERRORE funzione(0) NEW ] \n";
}
catch (int ER) { cerr << "\n con [ catch (double ER) ], (double ER) raccoglie il tipo\n di errore lanciato da throw, ER e'usato come variabile \n"; cerr << " Abbiamo raccolto l'errore numero ER: " << ER << endl;
cerr << "\n (Puo seguire altre istruzioni sul tipo di errore\n e come risolvere il problema.) \n";
}
catch (char * stringa)
{ cerr <<"\n----------------------------------------------"<< "\n\n con [ catch (char * stringa) ], raccoglie \n il tipo di errore lanciato da throw,\n nell' [else throw \" NEW ERRORE funzione(0) NEW \"] \n e raccogliamo l' errore \n "; cerr << stringa; cerr << "\n Abbiamo raccolto il nuovo errore\n\n"<<"-----------------------------------------------\n"; }
} int main() { cerr << " inizio delle eccezioni \n"; funzione(3); funzione(5.1);
funzione(0);
funzione('z');
cout << "\n Per USCIRE usiamo [ system (\"pause\") ] con i comandi di try\n si esce direttamente come se ci fosse un exit(1) \n "; system("pause");}
Possiamo raccogliere tutti i tipi di eccezioni senza dover avere per forza un specificato tipo, di solito l’ utilizzo di questo tipo di raccolta di errori viene fatto per ultimo come se fosse il
default
del comando
switch case
per la raccolta usiamo il comando
catch(…){blocco catch}
proprio i 3 puntini acconsente
qualsiasi tipo di dato ecco un programma sviluppato come è possibile vedere con una sola istruzione
catch(…)
posso avere
4 tipi diversi di dati
:
#include<iostream> using namespace std;
void funzione (int tER) { try
{ cerr << "\n Qui siamo dentro la funzione ora lanciamo una eccezione \n";
if (tER == 10) throw
tER;
if (tER == 20) throw
'E';
if (tER == 30) throw
1.20;
if (tER == 40) throw
67;
}
// nota
catch (...)
{ cerr << " catch raccoglie: "; } }
int main() { cout << " inizio delle eccezioni \n";
funzione(10); cerr << "{ Errore N 10 = intero da variabile } \n";
funzione(20); cerr << "{ Errore N 20 = carattere } \n";
funzione(30); cerr << "{ Errore N 30 = double } \n";
funzione(40); cerr << "{ Errore N 40 = intero da numero }\n";
cout << "\n\n [ Per USCIRE (1 tasto+invio) ] "; char a; cin>>a ; }
Era possibile usare anche 2 istruzioni catch per raccogliere solo la prima e l’ ultima ovvero la variabile
tER
(tipo_Errore) e l’ ultima il numero intero tutto il resto poteva essere raccolto con la catch(…) basta inserire questa nuova
catch(int)
prima della catch(…) e alla fine del blocco try nel punto dove su ho scritto
//nota
ecco il testo da inserire vediamo che i numeri interi passeranno per questa nuova istruzione :
catch (int) { cerr << "\n ---> raccolta numero intero ---> \n"; }
Un’ altro modo per usare le eccezioni è avere un elenco tipi dentro la funzione grazie alla definizione che può essere inserita dentro la stessa funzione dopo la normale funzione possiamo inserire
throw(tipo1,tipo2, ecc.. )
ritorniamo alla nostra funzione che abbiamo sempre usato e la modifichiamo:
void funzione (int tER) throw(int,char,double)
cosi throw riconosce solo i tipi descritti dentro le parentesi però non è veloce e comodo vediamolo in dettaglio con il solito programma ad ogni chiamata di funzione corrisponde un suo
try(funzione ())
e un suo
catch(tipo){istruzioni} :
#include<iostream> using namespace std;
void funzione (int tER)throw(int,char,double )
{ cerr << "\n Qui siamo dentro la funzione ora lanciamo una eccezione \n";
if (tER == 10) throw tER;
if (tER == 20) throw 'E';
if (tER == 30) throw 1.20;
if (tER == 40) throw 67;
} int main() { cout << " inizio delle eccezioni \n";
try { funzione(10); } catch (int i)
{ cerr << "\n raccolta numero intero > " << i << "\n";
cerr << "{ Errore N 10 = intero da variabile } \n"; }
try { funzione(20); } catch (char c)
{ cerr << "\n raccolta numero char > " << c << "\n";
cerr << "{ Errore N 20 = carattere } \n"; }
try { funzione(30); } catch (double d)
{ cerr << "\n raccolta numero double > " << d << "\n";
cerr << "{ Errore N 30 = double } \n"; }
try { funzione(40);} catch (int i)
{ cerr << "\n raccolta numero intero > " << i << "\n";
cerr << "{ Errore N 40 = intero da numero }\n"; }
cout << "\n\n [ Per USCIRE (1 tasto+invio) ] "; char a; cin>>a ; }
sempre con throw possiamo rilanciare uno stesso errore basta utilizzare
throw;
vediamo dentro la funzione rilanciamo
throw
, poi nel
main()
richiamiamo l’ eccezione tramite
catch (int m);
:
#include<iostream> using namespace std;
void funzione () { cerr << "\n Qui siamo dentro la funzione \n lanciamo una eccezione:";
try { throw 101; } catch (int i) { cout << " Errore n " << i << "\n";
throw;
} }
int main ()
{ cout << " Inizio dell' eccezioni \n";
try { funzione(); }
catch (int m) {cout << "\n Raccolta 2a eccezione in main\n Errore n " <<m <<"\n";}
cout<< "\n\n [ Per USCIRE (1 tasto+invio) ] "; char a; cin >> a; }
La cosa migliore per usare le eccezioni è quella di usare le classi in modo che incassa, grazie all’ incapsulamento delle stesse classi, tutte le informazioni che riguarda l’ eccezione e ogni classe deve avere il proprio errore sviluppo un programma cattura errori, se il risultato di una divisione ci porta sotto lo 0.01
allora è errore perché è un numero negativo ecco il programma sviluppato se lo copiate direttamente ricordate per farlo funzionare bisogna spostare almeno using namespace std ; che va sotto l’ #include<iostream> per il resto può rimare uguale altrimenti per ogni graffa aperta o chiusa e dopo ogni punto e virgola si va con la nuova riga, eccetto per le 2 funzioni costruttore inline ecco il rapporto :ho creato la classe
classe_errore1
dove si costruisce il rapporto dell’ errore, tipo e numero errore il numero viene catturato da
int errore;
e successivamente da
err
, mentre il tipo nome viene catturato dal array
char array_errore[80];
poi successivamente sarà
arr
, poi abbiamo preso 3 variabili per creare la divisione
double numero, num1, num2;
, con il
do {… } while (num1 != 0);
ho creato il ciclo finche il primo numero immesso è diverso da 0 si gira , quando num1 è uguale a 0 si esce dentro il
try
si controlla che il numero ovvero il risultato della divisione non sia minore di 0.01
if (numero <= 0.01)
in questo caso throw lancia l’ errore chiamando la funzione costruttore posizionata dentro la classe
throw classe_Errore1(numero , " <<< ERRORE questo numero e' negativo\n uguale o minore di 0.01 >>> ");
la chiamata è per la
classe_Errore1
con
catch (classe_Errore1
oe
)
abbiamo catturato il tipo errore e con lui abbiamo creato l’ oggetto della classe per le chiamate
oe
cerr <<
oe.
array_Errore << " -" <<
oe.
errore
#include<iostream> using namespace std;
class
classe_Errore1
{ public:
int errore;
char array_Errore [80];
classe_Errore1() {
errore = 0;
*array_Errore = 0;
}
classe_Errore1(
int err
,
char *arr
) { strcpy(
array_Errore , arr
);
errore = err;
} };
int main () {
double numero, num1, num2;
do {
cout << " > Cattura errori che sono i numeri negativi \n i numeri positivi non sono errori <\n\n { per numeri negativi si considera numeri sotto lo 0.01 } \n " <<"\t <[[per uscire dal ciclo immettere 0]]>\n";
try
{ cout << "\n Immettere due numeri positivi:\n" <<" immettere primo numero "; cin >> num1;
cout << " ... secondo numero "; cin >> num2; system ("cls");
cout << "calcolo divisione... tra " <<num1 << " / "<<num2<<"\n" ;
numero = num1 / num2; cout << "\n\n risultato [" << numero <<"]\n\n";
if (numero <= 0.01)
{ cout << endl;
throw classe_Errore1(numero , " <<< ERRORE questo numero e' negativo\n uguale o minore di 0.01 >>> ");
} }
catch (classe_Errore1
oe
)
{
cerr <<
oe.
array_Errore << " -" <<
oe.
errore
<< "\n\n"; }
} while (num1 != 0);
system("cls"); cout << "\n\n USCITA [premere un tasto+ invio] "; char zx; cin >> zx; }
Quando si usa eccezioni per classi derivate da classi base bisogna prima raccogliere le eccezioni per la classe derivata poi si deve raccogliere gli errori per la classe padre, conseguenza se si raccoglie prima le eccezioni tramite la funzione catch quella della classe padre poi il catch non leggerà più errori nella classe figlia perché in catch ogni classe padre o base risponde ad una classe figlia o derivata ogni catch della classe primaria raccoglie errori anche per la classe secondaria
Nel caso che una eccezione lanciata da
throw
non viene trovata ecco che il compilatore o il sistema stesso richiama le funzioni
void unexpected();
e
void terminate();
queste funzioni fanno parte della
libreria std del C++
tramite
l’header <exception>
, normalmente quando una funzione lancia un errore non consentito da throw il compilatore richiama la funzione
unexpected();
che richiama la funzione
terminate();
. Quando il sistema non trova l’ istruzione
catch
corrispondente a quel tipo di errore, oppure quando il programma rilancia errori che non ci sono, allora viene richiamata la funzione
terminate ();
che richiama la funzione
abort();
che serve per uscire da un qualsiasi programma in qualsiasi circostanza di errore
Ciao grazie da ByMpt-Zorobabele
Testo PDF aggiornato con questo ultimo capitolo inserito lo trovate :
http://www.freeforumzone.com/d/11266858/Elenco-figure-dei-comandi-della-programmazione-C-TESTO-PDF/discussione.aspx
Anche qui di queste discussioni che inserisco faccio un testo PDF da poter scaricare tutto il mio materiale è da utilizzare come desiderate per il testo PDF vedi cartella dedicata , ogni volta cambia ubicazione del testo allora cambio il file e il testo lo inserisco
dentro la cartella < file aggiornato ad oggi >
http://www.freeforumzone.com/d/11266858/Elenco-figure-dei-comandi-della-programmazione-C-TESTO-PDF/discussione.aspx
1
5
MediaObject
1,00
11
1
Tag discussione
programmarecpp
cpp programmazione
eccezioni cpp
errori cpp
try throw catch
gestione delle eccezioni
gestioni errori
bympt-zorobabele
funzione abort
funzione terminate
funzione unexpected
libreria std
throw
catch
try
programmi cpp
Registrati
Accedi
INDICE Appunti sulla programmazione C++
Accedi
IL MIO PROFILO
LE MIE DISCUSSIONI
FORUM CHE SEGUI
LA MIA FORUM-CARD
MODIFICA FORUM-CARD
FAQ
TRADUCI
LOGOUT
Accedi
Registrati
FAQ
TRADUCI
Scatta o carica foto
Allega file
Inserisci link da url (card)
Incorpora url (YouTube/Twitter/...)
ACCETTA
RIFIUTA
Anteprima