Newsgroup: it.comp.lang.c++
Titolo: passare il puntatore di un oggetto

ciao!
se voglio passare per riferimento un oggetto (ad una funzione) per far
si che possa essere modificato, faccio così:
struct tObj2 {
char A;
};
struct tObj {
unsigned int field1;
tObj2 field2;
};
void my_f(tObj &obj) {
obj.field1=0;
obj.field2.A='X';
}
void main {
tObj main_obj;
my_f(main_obj);
}
tutto OK
se invece definisco la funzione così:
void my_f(tObj *obj) {
obj.field1=0;
obj.field2.A='X';
}
e la chiamo con my_f(&obj) mi da un errore in compilazione;
perchè?

 perchï¿œ?
Verifica la differenza che c'ï¿œ nei passaggi di parametri per valore e 
per riferimento.
ciao
-- 
Morde

 perch�?
perch� se passi un puntatore la dereferenzazione deve essere esplicita...
ergo usa:
obj->field1
oppure
(*obj).field1

 (*obj).field1
ok
ma che differenza c'è in pratica fra definire una funzione così:
void my_f1(tObj &obj) {obj.field1=0;}
oppure così:
void my_f2(tObj *obj) {obj->field1=0;}
in entrambi i modi riesco sempre a modificare "globalmente" i campi
dell'oggetto che passo come argomento alla funzione, giusto?

 dell'oggetto che passo come argomento alla funzione, giusto?
Ovviamente sï¿œ, ï¿œ implicito nel disegno: tu hai definito una funzione 
che accetta come parametri il puntatore o il valore di un oggetto, 
quindi significa che l'hai disegnata proprio perchï¿œ operi in qualche 
modo su quell'oggetto.
ciao
-- 
Morde

 modo su quell'oggetto.
ok, grazie;
ma la scelta di definire una funzione in un modo o nell'altro comporta
vantaggi/svantaggi?
(sempre parlando di oggetti che devono essere modificati dalla
funzione stessa e che quindi all'uscita dalla funzione mantengano le
modifiche apportate)
1. void my_f1(tObj &obj) {obj.field1=0;}
2. void my_f2(tObj *obj) {obj->field1=0;}
-ice-

 vantaggi/svantaggi?
Fai attenzione a non confondere il modo in cui passare i parametri alla 
funzione!
Tu hai definito nei post precedenti questi passaggi di parametri:
1) void my_f(tObj &obj)
2) void my_f(tObj *obj)
In tutte e due i casi, l'accesso all'oggetto ï¿œ ammesso. Nel primo caso, 
tramite l'indirizzo dell'oggetto, nel secondo tramite un puntatore 
all'oggetto.
Ma per capire bene come puoi *scegliere di passare dei parametri* ad 
una funzione, guarda questa pagina:
http://pages.cs.wisc.edu/~hasti/cs368/CppTutorial/NOTES/PARAMS.html
Come si legge bene nell'articolo, tu puoi passare anche la copia di un 
oggetto. In quel caso la funzione modificherï¿œ una copia dell'oggetto 
senza intaccare l'originale.
Poi sta a te progettare funzioni che lavorino su copie o su 
riferimenti/puntatori agli oggetti.
Ti dï¿œ uno spunto su cui ragionare nel progettare le tue chiamate a 
funzioni: in c++ tu puoi passare ad una funzione un riferimento ad un 
oggetto, e quindi hai accesso in scrittura a quell'oggetto e all'area 
di memoria dove risiede lo stesso. Java, per evitare il pericolo di 
sovrascrivere un oggetto, di default tutti i passaggi di parametri li 
fa per valore, cioï¿œ effettuando una copia dell'oggetto passato. In 
questo modo l'oggetto originario viene protetto dalle sovrascritture 
quando viene passato ad una funzione.
In c++ puoi prevenire la sovrascrittura dell'oggetto anteponendo 
*const* al suo reference quando viene passato alla funzione.
Ragiona bene su questo aspetto quando scrivi le funzioni e definisci il 
passaggio dei parametri. C++ ï¿œ potentissimo ma allo stesso modo, se 
usato in modo poco accorto, puï¿œ fare danni incalcolabili perchï¿œ i bug 
dovuti alle sovrascritture sono difficilissimi da tracciare..
Ciao
-- 
Morde

 dovuti alle sovrascritture sono difficilissimi da tracciare..
intanto grazie per i suggerimenti
sto leggendo il link i cui concetti mi sono bene o male tutti noti;
il mio dubbio è probabilmente legato alla poca esperienza dato che il
C lo uso praticamente solo per micro in cui non c'è fisicamente la ram
per pensare ad allocazione dinamica o passaggio di parametri complessi
curiosità: se in java passi tutto per valore, come fai ad ottenere una
funzione che modifichi il contenuto degli oggetti che passi?
tornando a noi, correggimi se sbaglio, dal punto di vista del
risultato non c'è differenza a definire una funzione che accetta un
oggetto per riferimento oppure che accetta il puntatore all'oggetto
in entrambi i casi infatti le eventuali modifiche all'oggetto sono
permanenti (non solo locali insomma)
nel caso si scelga di passare il puntatore all'oggetto, il puntatore
stesso NON potrà essere modificato dalla funzione in modo globale
-ice-

 funzione che modifichi il contenuto degli oggetti che passi?
Mi sono espresso male e ti ho confuso, scusami: questo argomento del 
passaggio per valore porta sempre confusione....dovevo specificare che 
la copia viene fatta sia sui tipi primitivi che sui reference.
Cioï¿œ, se tu scrivi
mioOggetto pippo = new MioOggetto(....);
Metodo( pippo )
viene passato a metodo la copia *del reference* a pippo.
Di conseguenza puoi fare pippo.MetodoSetter() e modifichi l'oggetto 
referenziato da pippo.
ciao
-- 
Morde