Un riferimento ha uno scopo: agire come alias per una variabile esistente:
int i;
int &ri = i;
In questo esempio, gli indirizzi di i
e ri
sono identici ( &i == &ri
). I due nomi si riferiscono alla stessa posizione in memoria. Quindi una delle applicazioni utili dei riferimenti è fornire un alias per un nome lungo che sarebbe uno spreco da ridigitare:
const Location& p = irresponsibly_long_object_name.retrieve_location();
Quando si passa un parametro di funzione per riferimento, ha lo stesso effetto:
void increment(int& parameter) { ++parameter; }
int main(int argc, char** argv) {
int variable = 0;
increment(variable);
}
Qui parameter
funge semplicemente da alias di variable
, proprio come se fosse definito come int& parameter = variable
. La modifica di parameter
all'interno di increment()
è indistinguibile dalla modifica di variable
in main()
. Inoltre, e questo è abbastanza utile, variable
non ha bisogno di essere copiato; quindi se fosse di un tipo grande come std::list<int>
, passarlo per riferimento sarebbe molto più efficiente. Questo è il punto principale di const
riferimenti.
Ai fini dei parametri di funzione del tipo di riferimento, la linea di azione più corretta per un compilatore è di usare un puntatore internamente, come se avessi scritto:
void increment(int* parameter) { ++*parameter; }
int main(int argc, char** argv) {
int variable = 0;
increment(&variable);
}
Questo è un dettaglio interessante e vale la pena di ricordare. Anche se non è essenziale per la comprensione dei riferimenti, riconoscere questa equivalenza consente di pensare ai puntatori semplicemente come riferimenti espliciti . Allo stesso modo, i riferimenti sono puntatori impliciti.