Newsgroup: it.comp.lang.c++
Titolo: Copia classi

Salve a tutti,
ecco il mio problema:
supponete di avere una classe BASE 'B' e un classe DERIVATA 'D'.
Se dichiaro due oggetti di tipo D a, b e faccio a = b; il compilatore mi fa
una copia superficiale e copia le variabili membro pari pari (tutte quante,
sia private che pubbliche, sia della parte derivata che della parte
ereditata).
Nel momento in cui devo provvedere io a scrivere una funzione per la copia
(operatore di assegnazione o costruttore di copia) per la classe derivata D,
come faccio ad accedere ai membri privati della classe base B?
Faccio un rapido esempio:
class Base
{ public: int x;
  private int priv;
}
class Derivata public Base
{  public: int y;
    Derivata & operator= (...)       // Scusate magari per la sintassi se
può essere scorretta, ma non la ricordo molto bene
}
quando definisco operator, e devo copiare la variabile privata "priv", come
faccio?
Devo usare costrutti tipo friend o roba varia?
Grazie a tutti,
spero di essere stato abbastanza chiaro.
Giovanni.

Le variabili private sono accessibili solo dalla classe base, al massimo
potresti implementare dei metodi nella classe base che ti ritorni il valore
delle variabili membro, altrimenti utilizzando la classi amiche le variabili
dovresti dichiararle protect invece che private in modo da essere
accessibili dalla classe derivata e amica..
Se ho detto tutte fesserie perdonatemi, ma ho detto quello che mi ricordo...
CIAO.


Quasi giusto: se dichiari D come friend di B (con i problemi di "forward 
declaration" del caso), allora le variabili di B possono rimanere 
private. Se invece le dichiari protected (che, in questo contesto, 
sembra la scelta migliore), D potra' accedere liberamente alle variabili 
protected di B, senza esserne friend.
-- 
Mat/tia Belletti - Undergraduate student @ 
cs.unibo.it
ICQ: 33292311    - email: 
mbel...@cs.unibo.it
IRC: RedGlow     - site(s): 
http://www.cs.unibo.it/~mbellett
Linux registered user 299762 @ Linux registered machine 213003

...



   Derivata();
   Derivata(const Derivata & copyFrom);
   Derivata & operator=(const Derivata &);
};
Derivata::Derivata()
{}
Derivata::Derivata(const Derivata & copyFrom)
  :Base(copyFrom)
{
   y = copyFrom.y;
}
Derivata & Derivata::operator=(const Derivata & copyFrom)
{
   Base::operator=(copyFrom);
   y = copyFrom.y;
   return *this;
}
int main()
{
   Derivata a,b;
   a = b;
   Derivata c(a);
   return 0;
}
ciao.
Marco.

In sostanza quindi richiami l'operatore di assegnazione per la classe base
passandogli cmq l'oggetto derivata.
In questo modo viene effettuato automaticamente un object slicing e funziona
giusto?
Ho capito bene?
Grazie
Giovanni.

...

L'operatore di assegnamento ha (solitamente e in particolare in questo
esempio) come parametro un 'const &'. Quindi questo non è un caso di
"object slicing" che avviene nei casi di funzioni in cui si utilizza
il passaggio per VALORE (in cui quindi viene creata una variabile
temporanea).
In questo caso non viene creata alcuna variabile temporanea e questa
tecnica permette di inizializzare la classe base senza rendere
public/protected le variabili.
Ciao.
Marco.

 ha scritto nel messaggio
news:a33fe984.04062...@posting.google.com...

Ma scusa, tu hai scritto:
Derivata & Derivata::operator=(const Derivata & copyFrom)
{
   Base::operator=(copyFrom);
   y = copyFrom.y;
   return *this;
}
Cosa significa "Base::operator=(copyFrom);" ?
Io pensavo che in un qualche modo si potesse richiamare l'operatore di
assegnazione relativo alla classe base passandogli come parametro l'oggetto
derivata (ecco quì lo slicing) in modo da modificare solo la parte base
dell'oggetto derivata.
Questa istruzione che significa quindi?
Nell'esempio poi non hai nemmeno definito un operatore di assegnazione per
la classe base.
Giovanni.

 la classe base.
In questo caso viene creato dal compilatore l'operatore di
assegnamento di default che effettua una copia byte per byte.
ciao.
Marco.

 la classe base.
L'operatore assegnamento della classe base viene implicitamente definito 
dal complilatore.
(Ovviamente, nell'esempio in questione non era necessario definire alcun 
operatore assegmento o costruttore copia; ci avrebbe pensato il compilatore 
comunque, sia per la classe base che per quella derivata.)
Max

 la classe base.
Forse perche' quello sintetizzato dal compliatore va bene cosi'
com'e'...
Ciao,
Nicola

In effetti forse il termine slicing è improprio,
però quando passo l'oggetto derivata all'operatore = per la classe base (il
quale si aspetta un oggetto di tipo base) in realtà viene considerata
solamente la parte base della classe derivata.
E' vero che è passata per riferimento, però avviene lo stesso meccanismo di
quando si fa una copia e c'è lo slicing, ossia dell'oggetto derivata viene
considerata solo la parte base.
Chiedo scusa se insisto, ma è giusto per capire... :-)
Grazie per le risposte.
Giovanni.