Newsgroup: it.comp.lang.c++
Titolo: char *message o char message[..] ?

 equivale a const char *message="attempted..."; ?
Si, visto che vien fatta dalla riga di inizializzazione del costruttore, 
e quindi message vien direttamente inizializzato cosi`.
Peraltro, poteva risparmiarsi anche il puntatore e  andar dritto di
const char *
DivideByZeroException::what(void) const
{
     return "attempted to divide by zero";
}
e, gia` che c'era , magari dichiararla anche virtual, cosi` se vien 
lanciata come eccezione, chi la intercetta per riferimento ad una classe 
base riesce comunque a beccarsi il messaggio giusto della derivata.
-- 
   |   \    \  | ___|_  |_  | ianezz a casa sua... :-)
   |  _ \  | \ | _|    /   /  Visita il LinuxTrent a
  _|_/  _\_|  _|____|___|___| 
http://www.linuxtrent.it

 base riesce comunque a beccarsi il messaggio giusto della derivata.
Uhm, ripensandoci, meglio usare un approccio diverso, con un costruttore 
protected che serva alle classi derivate per impostare un messaggio piu` 
specifico.
Ha due vantaggi: non serve dichiarare what() virtual, e il costruttore 
di copia e l'operatore di assegnazione generati automaticamente dal 
compilatore conservano il messaggio della derivata anche quando si 
costruisce per copia una classe base da una derivata, o si assegna una 
derivata ad una base.
Esempio pratico:
----------------------------------------------------------------------
#include <iostream>
using namespace std;
//////////////////////////////////////////////////////////////////////
// Classe base delle nostre eccezioni
//////////////////////////////////////////////////////////////////////
class ExceptionBase
{
public:
     ExceptionBase(void)
	:
         m_message("Eccezione base")
     {}
     const char *
     what(void) const { return m_message; }
protected:
     // Costruttore protected usato dalle classi derivate
     ExceptionBase(const char * msg)
         :
         m_message(msg)
     {}
private:
     // Il messaggio lo tocca direttamente solo questa classe.
     // Gli altri devono passare per il costruttore protected
     const char * m_message;
};
//////////////////////////////////////////////////////////////////////
// Classe derivata (corta, neh?)
//////////////////////////////////////////////////////////////////////
class ExceptionDerived : public ExceptionBase
{
public:
     ExceptionDerived(void) : ExceptionBase("Eccezione derivata") {}
};
//////////////////////////////////////////////////////////////////////
int
main()
{
     // Questa e` l'eccezione derivata.
     ExceptionDerived e_derived;
     // E questa ne e` una copia, ma notare che e`
     // un oggetto ExceptionBase, e non ExceptionDerived.
     ExceptionBase  e_base(e_derived);
     // E, tuttavia, qui salta fuori (intenzionalmente)
     // il messaggio della derivata.
     cout << "Da una costruzione per copia: " << e_base.what() << endl;
     // Questa e` un'altra eccezione base.
     ExceptionBase  e_other_base;
     cout << "Base, prima di assegnare: "
          << e_other_base.what()
          << endl;
     // Assegnamoci la derivata
     e_other_base = e_derived;
     cout << "Base, dopo l'assegnamento: "
          << e_other_base.what()
          << endl;
     return 0;
}
----------------------------------------------------------------------
Se poi si usa std::string come tipo per il messaggio (invece che const 
char *), e si cambiano opportunamente i "const char *" in "const 
std::string &", possiamo mettere come messaggio tutto quello che 
vogliamo, anche generato dinamicamente (visto che il costruttore di 
std::string si fa una copia sua), senza nemmeno dover dichiarare 
esplicitamente un distruttore.
Chiaro, peserebbe un poco di piu` per via della costruzione della 
std::string per copia da una costante stringa, ma la copia di una 
std::string dovrebbe essere svelta.
