Newsgroup: it.comp.lang.c++
Titolo: Richiamare costruttore?

Scusate, ma è corretto richiamare un costruttore da un altro
costruttore?
Ciao_______________
http://siena.linux.it
 -  S L U G  homepage
Leva "civetta" dal mio indirizzo.
http://dinogen.tripod.com
 - la mia homepage

Generalmente no. Cosa stai cercando di fare?
Ciao,
Nicola

 Generalmente no.
Come no?  Questo mi sembra un idioma comune:
class A {
  private:
    string s;
  public:
    A(const char *pc) { s = string(pc); }
    // Oppure: A(const char *pc) : s(pc) { }
};
-- 
Maurizio Loreti                         
http://www.pd.infn.it/~loreti/mlo.html
Univ. of Padova, Dept. of Physics - Padova, Italy            
lor...@pd.infn.it
The instructions said to use Windows 98 or better - so I installed FreeBSD.

 };
Formalmente questo e' un "functional notation cast" ed equivale al
classico cast del C. Il fatto che scateni la chiamata ad un costruttore
e' un dettaglio interno. Tra l'altro salvo per costruttori dichiarati
explicit la conversione avviene gia' implicitamente.
Ciao,
Nicola

Generalmente no. Cosa stai cercando di fare?
Perche' no ?
Nel caso seguente non si ha una chiamata esplicita ?
#include <iostream>
using namespace std ;
class A {
      private:
         int x ;
      public:
         A() { cout << "sono nel costruttore di A" << endl ; }
} ;
class B {
      private:
         A* ptr_my_class ;
      public:
         B() {
               ptr_my_class = new A() ;
               cout << "sono nel costruttore di B" << endl ;
               delete ptr_my_class ;
             }
} ;
int main()
{
    B mia_classe ;
    return 0 ;
}
--
Andrea Laforgia (ICQ 87230455)
http://www.geocities.com/AndreaLaforgia
"ci sono tre tipi di persone nel mondo : quelli che
 sono bravi in matematica e quelli che non lo sono."

 }
Ciao,
Nicola

Come no?  Questo mi sembra un idioma comune:
Mi sono spiegato male, volevo dire un costruttore che richiama un
altro costruttore della stessa classe.


 altro costruttore della stessa classe.
Se intendi chiamarlo per costruire l'oggetto stesso la risposta e' no.
Ma ovviamente nulla di impedisce di costruire un'altro oggetto della
stessa classe. In questo senso potresti trovarti in una situazione in
cui un costruttore finisce per richiamare un altro costruttore della
stessa classe.
Per esempio:
class Gemelli {
private:
    Gemelli *pMioGemello;
    Gemelli(Gemelli*pAltro):pMioGemello(pAltro){}
    Gemelli():pMioGemello(new Gemelli(this)){}
public:
    static Gemelli*creaNuovaCoppia(){ return new Gemelli; }
    Gemelli*gemello() const { return pMioGemello; }
    ~Gemelli(){ gemello()->pMioGemello=0; delete pMioGemello; }
};
Andrea Ferro
---------
Brainbench C++ Master. Scored higher than 97% of previous takers
Scores: Overall 4.46, Conceptual 5.0, Problem-Solving 5.0
More info 
http://www.brainbench.com/transcript.jsp?pid=2522556

 altro costruttore della stessa classe.
Per la stessa istanza non si puo' fare.
	Mauro

    ~Gemelli(){ gemello()->pMioGemello=0; delete pMioGemello; }
BUM! ... il gemello si trova ad avere gemello() che
restituisce il puntatore nullo ma nel distuttore
dereferenzia questo puntatore (con effetti imprevedibili).
Come scritto il test evita un loop infinito, ma non il
dereferencing di NULL. Dovrebbe diventare
   ~Gemelli()
   {
     if (gemello())
     {
       gemello()->pMioGemello=0;
       delete gemello();
     }
   }
Andrea
--
Andrea Griffini, Programmer
http://www.netservers.com/~agriff

altro costruttore della stessa classe.
No... purtroppo la sintassi C++ permette di scrivere qualcosa che
trae in inganno ed e' un errore abbastanza comune...
   class MyClass
   {
     public:
       // costruttore di default
       MyClass()
       {
         ...
       }
       // Altro costruttore
       MyClass(MyDataStream ms)
       {
         // Crede di chiamare il costruttore di default
         MyClass();
         ...
       }
     ...
   };
In questo caso la riga "MyClass()" del secondo costruttore
non sta chiamando il costruttore di default sull'istanza
corrente ma sta invece creando una *altra* istanza usando
il costruttore di default e immediatamente dopo questa
istanza viene buttata via.
L'unico modo di chiamare un costruttore e' costruendo
un *nuovo* oggetto.
Quello che puoi fare e' mettere le inizializzazioni
"comuni" che ti servono nei vari costruttori in un
metodo privato e poi richiamare questo metodo (diciamo
"init") all'inizio di tutti i costruttori.
HTH


 altro costruttore della stessa classe.
Andiamo gia' meglio (la mia risposta precedente era ironica, BTW;
forse un po' troppo terra terra per essere riconosciuta).  In casi
come questo (la costruzione di un oggetto richiede di fare un sacco di
cose) usa definire un metodo privato che effettua la costruzione
stessa, e che viene richiamato dai vari costruttori (di default, di
copia, ...) e dall'assignment operator; e magari un altro metodo
privato che distrugge l'oggetto e che viene richiamato sia dal
distruttore che dall'operatore di assegnazione.  Tipo:
class A {
  private:
    build(//vari parametri) { // Costruisci un'istanza }
    nuke() { // Distruggi un'istanza }
    ...
  public:
    A() { build(...); }
    A(const A & a) { build(...); }
    ~A() { nuke(); }
    const A & operator = (const A & rhs) {
      if (this != &rhs) { nuke(); build(...); } return *this; }
    ...


 BUM! ... il gemello si trova ad avere gemello() che
Si. Hai ragione.
Quello che succede scrivendo il codice direttamente in outlook, cosi'
di getto e senza pensarci. Se anche solo avessi scritto un minimo di
commento su cosa facevo e perche' ... me ne sarei accorto.
Vabbe', sentenza: 2 minuti di autoflagellazione spietata.


altro costruttore della stessa classe.
Se intendi farlo sullo stesso oggetto non si può fare e credo che sia
un bene, perché si tratterebbe sicuramente di un caso di
programmazione poco pulita, ed inoltre credo che sia anche una cosa
inutile. Molto meglio crearsi una funzione membro privata o protetta
da richiamare all'interno del costruttore.
Il Ghenio
WINWORD.EXE - ERRORE DI APPLICAZIONE
l'istruzione a "0x3017ff27"ha fatto riferimento alla
memoria a "0x02a3143c".La memoria non poteva essere 'read'.

un *nuovo* oggetto.
Non e' possibile scrivere codice terribile come:
//costruttore di default
Papero::Papero()
{
//a questo punto dovrei essere bello che costruito
//mi distruggo, ma non mi disalloco
  this->~Papero();
//riutilizzo la memoria per richiamare il secondo costruttore
//che piglia delle anitre come parametro
  new(this) Papero( anitre(simpatiche) )
}
Certo, spararsi in bocca mi sembra una via piu' rapida per morire.
Non sono nemmeno sicuro della sintassi.
-- 
Tieni per te il Papero se vuoi la mia email
Sito Papero -> 
http://utenti.tripod.it/papero

 Non sono nemmeno sicuro della sintassi.
Tecnicamente stai comunque costruendo un altro oggetto. Anche se lo
fai allo stesso indirizzo.
Comunque sei perverso mica male!
Vabbe' che dicono che I paperi pigliano come mamma il primo essere che
vedono, ma con te Edipo ci deve essere andato giu' duro! ;-)


}
Gia', e' davvero possibile spararsi sui piedi, ma perche' farlo? (B.S.
dice che se ti spari sui piedi in C++, perdi l'intera gamba!!!). Il
codice in se' non dovrebbe essere molto pericoloso, ma dovrebbe essere piu'
conveniente (anche per quanto riguarda le prestazioni) modificare direttamente
l'oggetto (visto che si tratta dello stesso oggetto, a meno di casi
particolari...), anziche' distruggerlo e poi ricrearlo (a meno che non si
tratti di un oggetto infetto da BSE, nel qual caso bisognerebbe annientarlo
totalmente!)
Ciao
Domenico Barra

Comunque sei perverso mica male!
Questa idea non e' mia. E' una variante sul tema che ho visto per la
prima volta nella mail list di Pescio, e che per altro non avevo
capito. In quel caso si faceva vedere che entro certi limiti dovuti
alla dimensione anche in C++ e' possibile che un oggetto diventi
un'altro a run-time.
Ultimamente leggendo B.S. ho capito cose che non avevo capito, e di
riflesso ho capito quell'esempio "accademico".


Questa idea non e' mia. E' una variante sul tema che ho visto per la
Ho visto qualcosa del genere anche sul draft dello standard.
Si tratta in ogni caso della creazione di un altro oggetto
(alla stessa locazione).
