Newsgroup: it.comp.lang.c++
Titolo: Clonare un oggetto

ciao a tutti... questa è la mia domandina... è possibile clonare un oggetto
di una determinata classe? faccio un esempio...
mettiamo una definizione di classe
class Pippo {
    Pippo();
    ~Pippo();
    // ci può essere qualsiasi cosa, comprese istanze di altre classi...
};
Pippo::Pippo() {
//...
}
Pippo::~Pippo() {
//...
}
// etc.
Pippo *x;
Pippo *y;
//...
x = new Pippo();
//...
// qui copiare in qualche modo x su y
//...
delete x;
//...
Come posso clonare x su y in modo che quando x viene distrutta y continua a
mantenere i dati?
(una cosa del tipo y = x immagino copi solo i puntatori... e quindi una
volta distrutto x anche y non ha più nulla... o sbaglio?)
la domanda magari è banale... ma non riesco ad arrivarci...
grazie anticipatamente a tutti...
ciao

 la domanda magari č banale... ma non riesco ad arrivarci...
Puoi fare in due modi. Uno e':
   y = new A(*x);
mentre l'altro e':
   y = new A;
   *y = *x;
La prima tecnica chiama il copy constructor, mentre la seconda chiama 
prima il default contructor e poi l'assignment operator. Se tali metodi 
sono definiti nella classe, vengono chiamati quelli definiti, altrimenti 
quelli generati dal compilatore. Questi ultimi copiano tutte le 
variabili membro di x su quelle corrispondenti di y.
-- 
     Carlo Milanesi
 
http://digilander.libero.it/carlmila

Grazie mille per la chiarezza e la semplicità... ho fatto come nella seconda
che hai detto e funziona che è una bellezza! :)
ciao e grazie ancora


 variabili membro di x su quelle corrispondenti di y.
Di solito pero' con "clonare" si intende una cosa un po' diversa. La
soluzione da te proposta presenta infatti due problemi:
- Il primo e' che se la classe A contiene puntatori a sua volta,
  questi saranno semplicemente copiati, e non e' detto che questa
  sia la scelta giusta;
- Il secondo e' che trattandosi di puntatori a priori non sai se x
  punta ad un oggetto di classe A o di una classe derivata.
La soluzione generale e' quella di definire nel modo opportuno il
costruttore di A e delle sue classi derivate e quindi di dotare tanto A
quanto le derivate di una funzione membro virtuale clone() definita
come segue:
class A {
  public:
    virtual A * clone() const { return new A(*this); }
};
class B : public A {
  public:
    virtual B * clone() const { return new B(*this); }
};  
E quindi chiamare
y = x->clone();
Ciao,
Nicola

  sia la scelta giusta;
[...]
sarà per questo che in uscita il programma mi va in crash? boh... proverò a
fare come mi suggerisci tu... intanto grazie

 fare come mi suggerisci tu... intanto grazie
Ma non avevi detto che funzionava?
Una possibile causa del crash e' l'esecuzione di "delete" nel 
distruttore su una variabile membro di tipo puntatore.
Infatti, in tal caso, come detto sopra, gli operatori generati dal 
compilatore si limitano a copiare il puntatore. L'unico oggetto puntato 
viene poi distrutto tramite entrambi i puntatori, un crash e' verosimile.
Pertanto, se il tuo oggetto e' il "proprietario" di un altro oggetto 
tramite un puntatore, devi procedere diversamente.
Un possibile rimedio e' definire tu stesso l'operatore di assegnamento, 
che deve avere la seguente firma:
Pippo &operator =(const Pippo &other);
