Newsgroup: it.comp.lang.c++
Titolo: costruttori ed eccezioni

dunque avrei una domanda probabilmente sciocca per chi è più 
ferrato :
dato che un costruttore, portroppo non ritorna nessun valore di 
ritorno esplicito nè ha modi semplici di comunicare al chiamante 
se tutto è OK o qualcosa è andato storto (quasi che escluda a 
priori che qualcosa possa andare storto), mi chiedo
esiste garanzia affidabile che se qualcosa va male in un 
costruttore, venga lanciata un'eccezione dal medesimo ?
Per andare storto intendo in generale, anche se poi il problema 
più comune che mi riesca a immaginare ricade in due categorie, 
grossomodo, la mancanza di memoria (o dinamica o persno di 
automatica) o la ricezione di parametri errati (in questo caso 
si presume un throw esplicito però, quindi non è in tema).
Inoltre, ammesso che il linguaggio garantisca il throw 
automatico di un'eccezione in caso di memoria mancante (dinamica 
o automatica), è sicuramente un'eccezione che può essere 
catturata da un catch (...) generico ?
Volendo catturare errori in modo più selettivo, che tipo avrebbe 
l'eccezione sollevata in modo trasparente all'utente ?
E' una cosa standard o ogni compilatore lancia sostanzialmente 
quel che gli pare (tipo e_no_mem e roba simile) ?
Grazie in anticipo per le risposte
ciao
Soviet_Mario

 l'eccezione sollevata in modo trasparente all'utente ?
 > E' una cosa standard o ogni compilatore lancia sostanzialmente quel > 
 > che gli pare (tipo e_no_mem e roba simile) ?
Non capisco la frase "trasparente all'utente", comunque sappi che tutte 
le eccezioni sollevate dalla libreria standard sono di tipo 
std::exception o derivate da essa, e si raccomanda di definire proprie 
eccezioni esclusivamente derivandole dalla classe std::exception o da 
classi derivate da essa. Tuttavia, usando una libreria che non segue 
questa raccomandazione, si potrebbe dover intercettare ecezioni di altro 
tipo tramite "catch (...)".
L'eccezione standard per la mancanza di memoria dinamica e' "std:bad_alloc".
-- 
     Carlo Milanesi
 
http://digilander.libero.it/carlmila

 Voglio capire quanto sono "ispezionabili" questi oggetti a runtime
Secondo me la cosa migliore e' utilizzare dei catch selettivi.
  bye
	av.

     av.


Ogni funzione, di una libreria o altro, deve dichiarare, almeno nella
documentazione, le eccezioni che possono essere lanciate dall'interno
della funzione. Una funzione che lancia un'eccezione non dichiarata è
formalmente difettosa.

 catturata da un catch (...) generico ?
Lo standard non garantisce il rilevamento di una condizione di
sforamento della memoria automatica.
Quando l'esecuzione di un costruttore viene interrotta da un'eccezione
vengono eseguiti tutti i distruttori di quei sotto-oggetti (classi
base e membri dato) dell'oggetto in questione la cui costruzione e'
stata completata, in ordine inverso rispetto a quello di completamento
dei costruttori.
Quindi le uniche operazioni "da disfare" sono quelle svolte nel corpo
del costruttore interrotto. Un buon motivo per cercare di fare il meno
possibile nel corpo dei costruttori.
Ciao,
Nicola

 non generale che si appoggia alle mie classi specifiche di eccezioni).
E che problema c'e'?
Ricordati solo di derivare le tue classi da std::exception.
  bye
	av.

 formalmente difettosa.
Si, ma in un mondo perfetto.
In pratica in una funzione non banale chiamerai altre funzioni, magari 
non scritte da te e cosi' via ricorsivamente. Basta che una sia 
"formalmente difettosa", che lo diventano quasi tutte quelle che la 
chiamano.
Nota anche che, se non si specificano restrizioni, e' da assumere che 
una funzione possa lanciare qualunque cosa.
  bye
	av.

 oggetto di una classe (e quale, nel caso) ?
 > Ma più in generale, come indagare, a runtime, e ottenere info sul
 > typename di un'eccezione non lanciata dal proprio codice sorgente ma
 > da codice delle librerie ?
Vedi il manuale e gli altri post.
Spero di aver chiarito i dubbi.


 una funzione possa lanciare qualunque cosa.
Se si specificano restrizioni comunuque *può* lanciare qualunque cosa.
Non *dovrebbe*, e se lo fa sono cazzi.
-- 
blog:  
http://www.akropolix.net/rik0/blogs
 | Uccidete i filosofi,
site:  
http://www.akropolix.net/rik0/
      | tenetevi riso e
forum: 
http://www.akropolix.net/forum/
     | bacchette per voi.

Andrea Venturoli ha scritto:
grazie delle dritte, ora me le studio un po' meglio e ci 
rimugino su.
Mi pare cmq, già ora, di capire che il miglior compromesso a cui 
possa giungere senza poter contare sulla pur magra WHAT (), sia 
quello di catch(...) in locale e rethrow di un'eccezione 
personalizzata derivata da std::exception
ciao
Soviet_Mario

 dinamica, in modo da individuare univocamente l'errore
Leggiti questo:
 
 
http://www.gotw.ca/publications/using_auto_ptr_effectively.htm
Max

  
http://www.gotw.ca/publications/using_auto_ptr_effectively.htm
Subito dopo suggerisco di darsi un'occhiata agli smart pointer
prefabbricati dentro boost.
In ultima analisi suggerisco anche l'acquisto di Effective C++ di
Meyers. Divertente da leggere e molto istruttivo. Ci sono altri libri
'analoghi', io consiglio questo perchè è quello con cui mi sono trovato
meglio, semplicemente.


 zero che scrivere i blocchi try/catch, ove possibile.
Questo uso e' deprecato pero', in quanto "new" rende 0 solo se la sua 
allocazione fallisce, ma se nel costruttore dell'oggetto viene sollevata 
un'eccezione, questa passa comunque.
Se sei tu a scrivere il costruttore, e dentro il costruttore ti fallisce 
una new, non puoi comunicare in nessun modo al chiamante che la 
costruzione e' fallita se non sollevando un'eccezione.


 alcun effetto.
Ah !!! Azzo, direi. Forse è un'eredità del C, ma sapevo che la 
doppia cancellazione di un oggetto era fonte di disastri. Ai 
tempi si applicava a malloc/free. Forse adesso la cosa è rimasta 
solo con l'invocazione esplicita e doppia dei distruttori, 
mentre la gestioen dinamica è stata irrobustita.
grazie delle dritte
ciao
Soviet


 Non *dovrebbe*, e se lo fa sono cazzi.
Giusto anche cosi'.
Diciamo che, se una funzione specifica cosa puo' lanciare, sai che non 
ti troverai ad intercettare altro che quei tipi di eccezione.
Se lancia qualcos'altro il programma termina.
  bye
	av.

 cancellazione di un oggetto era fonte di disastri.
E lo e'!
E' pero' lecito chiamare delete su un puntatore nullo.
Giusto:
T*a=null;
delete a;
Sbagliato:
T*a=new T;
delete a;
delete a;
Giusto:
T*a=new T;
delete a;
a=null;
delete a;
  bye
	av.

 a=null;
Accidenti, abbiamo un infiltrato javista. :)
Max

Max M. ha scritto:

Questa proprio non me la dovevi dire!!! :-)
Uso Java da un paio di mesi e gia' non ne posso piu' :-(
  bye
	av.

 Se lancia qualcos'altro il programma termina.
Esatto, a meno di macumbe :)


 E' pero' lecito chiamare delete su un puntatore nullo.
e iirc anche free.
