Newsgroup: it.comp.lang.c++
Titolo: Puntatori o reference? Perchè?

Ciao, sto trafficando da un pò con il C++ e
sto vedendo i reference... ma non capisco, in
che cosa un reference è diverso da un puntatore?
E quand'è che conviene usare l'uno invece dell'altro?
Grazie

 ha scritto nel messaggio
news:3D60B2C...@hotmail.com...

Ciao, anche io come te non è da molto che uso il c++ cmq credo di poterti
rispondere.
I reference sono una via di mezzo tra un puntatore e una variabile vera e
propria perchè: i reference contengono, come i puntatori, solo l'indirizzo
in memoria della variabile puntata, ma al contrario dei puntatori non si
deve puntare alla cella di memoria per poter utilizzare o modificare quella
cella, si usa come una normale variabile.
es:
#include <stdlib.h>
#include <iostream>
struct Persona {
    int Eta;
};
int main() {
    Persona Pippo; // variabile normale
    Persona *ptr_Pippo = &Pippo; // puntatore a Pippo
    Persona &ref_Pippo = Pippo; // reference che punta a Pippo
    ptr_Pippo->Eta = 20; // adesso l'età di Pippo è 20
    cout << "Putatore: " << ptr_Pippo->Eta << endl;
    ref_Pippo.Eta = 50;   // adesso l'età di Pippo è 50
    cout << "Reference: " << ref_Pippo.Eta << endl;
    system("PAUSE");
    return 0;
}
Non c'è una regola fissa sul loro uso(a quanto ne so), puoi usare entrambi a
tuo piacimento e quando ti sembra più adatto uno rispetto all'altro.
Ciao e buona programmazione
    Cristiano Ceglia

Cristiano Ceglia wrote:
 > Non c'č una regola fissa sul loro uso(a quanto ne so), puoi usare
 > entrambi a tuo piacimento e quando ti sembra piů adatto uno rispetto
 > all'altro.
Invece la regoletta c'e' (come mi e' stato insegnato a suo tempo da Cuni):
- i puntatori andrebbero usato *solo* dove e' possibile prendere valori
NULL. Esempio:
void dividi(int divid, int divis, int* risult, int* resto)
{
	if (resto != NULL)
		resto = divid % divis;
	if (risult != NULL)
		risult = divid / divis;
}
Se uno non e' interessato al resto, ci puo' passare un NULL per 4
parametro. Stessa cosa per il risultato. Poi, se uno ci passa due NULL
vuol dire che ha cicli macchina da sprecare ;-)
 
- i reference andrebbero usati in tutti gli altri casi, ovvero ovunque non
e' consentito avere puntatori NULL.
-- 
Andrea Bergia - studente
Linux Registred User #281550

 che cosa un reference è diverso da un puntatore?
Un puntatore contiene l'indirizzo di una locazione di memoria, mentre un
reference è un nome alternativo ad una locazione di memoria!
Esempio:
-puntatore:
int a = 1;
int *b = &a;// il puntatore ad intero b contiene l'indirizzo di a
 int c = &a;// c è un riferimento allo stesso indirizzo di memoria di a!
In pratica "a" e "c" indicano lo stesso indirizzo di memoria, mentre "b"
contiene "punta" quell'indirizzo di memoria, ma a differenza di "a" e "c"
"b" si riferisce ad un altro indirizzo!
variabile   contenuto    indirizzo
a               1               00000c1  ( gli indirizzi sono chiaramente
inventati)
b               00000c1   ffff0
c               1               00000c1
Mi auguro di essere stato chiaro!
Ciao
Francesco

 e' consentito avere puntatori NULL.
Ad es. li puoi usare quando devi passare oggetti come parametri di una
funzione, e sai che: o l'oggetto che passi non sarà modificato, oppure vuoi
che le modifiche si riflettano sull'oggetto effettivo. Infatti in un caso
simile:
class X {};
...
void f (X& obj) {};
int main() {
    X y;
    f (y);
};
la f() lavora sull' y del main e non su una copia. Non effettuando la copia
risparmi tempo e memoria. Ma questo sempre se ti trovi in uno dei due casi
che ho scritto sopra.
Ciao
--
Luigi

 riferimenti. Tramite i puntatori puoi utilizzare il polimorfismo, 
Questo anche coi reference.
Ciao,
Nicola

"Nicola Musatti" <Nicola....@ObjectWay.it> ha scritto nel messaggio
news:3D61FA81...@ObjectWay.it...

Puoi farmi un esempio? Io non so usare bene i reference quindi tutto quello
che tratta di questi mi fa gola :P
Ciao
        Cristiano

 che tratta di questi mi fa gola :P
#include <iostream>
class A {
  public:
    virtual int f() const { return 2; }
    virtual ~A() {}
};
class B : public A {
  public:
    virtual int f() const { return 3; }
};
int g(const A & a) {
  return a.f();
}
int main() {
  B b;
  std::cout << g(b) << std::endl;
}
Se non ho infilato errori di battitura stampa 3.
Ciao,
Nicola

 che ho scritto sopra.
Oppure puoi usare const X& obj e sei assicurato che nessuno ti 
modifichera' mai il tuo oggetto.


 modifichera' mai il tuo oggetto.
Beh, certo :)
Ciao
--
Luigi

 writes:
    sm> Ciao, sto trafficando da un pò con il C++ e sto vedendo i
    sm> reference... ma non capisco, in che cosa un reference è
    sm> diverso da un puntatore?
    sm> E quand'è che conviene usare l'uno invece dell'altro?
Tra i tanti  casi,  quando effettui overloading degli  operatori, vuoi
evitare di copiare ogni  volta gli oggetti, ma  vuoi evitare anche  di
dover ogni volta dereferenziare il puntatore, cosa che sintatticamente
puo` diventare pesante alla lettura.
ciao,
andrea
--
L'impressione che ho e` quella di una		   andrea glorioso 
democrazia violata: non capisco perche` come 
cittadino debba essere consultato sulla caccia,   
www.emergency.it
e non sulla caccia all'uomo		       
sa...@perchetopi.org

 l'indirizzo in memoria della variabile puntata, 
aspetta, non confondere quel che rappresentano i reference con il modo in 
cui sono implementati.
I reference sono, per definizione, dei nomi alternativi per riferirsi ad 
una medesima variabile: sta poi al compilatore trovare il modo per far 
si che questi "nomi alternativi" possano funzionare.
Ad esempio:
int main()
{
        int x = 0;
        int& y = x;
        x = 5;
        y = 5;
}
ho provato a compilare questo esempio con g++ e le ottimizzazioni al 
massimo e il compilatore genera esattamente lo stesso codice per 
entrambi gli assegnamenti: questo succede perche` il compilatore e` in 
grado di trovare gia` a compile time l'indirizzo di memoria referenziato 
da y e non c'e` bisogno di memorizzarlo in un puntatore.
Ovviamente questa ottimizzazione non e` sempre possibile:
        void foo( int& x );
in questo caso il compilatore non puo` determinare l'indirizzo a 
compile-time, per cui deve posticiparlo a run-time e passare un 
puntatore: pero` bisogna ricordarsi che si tratta comunque di dettagli 
implementativi, per cui l'equivalenza reference <-> puntatore non e` 
sempre vera.
ciao Anto
-- 
Antonio Cuni, 20 anni, studente
Brainbench C++ Master: 4.73, higher than 99% of all previous test takers.
C Language: 3.79, higher than 92% of all previous test takers.
Guida C/C++ di Programmazione.it: 
http://cpp.programmazione.it