Los punteros funcionan más o menos igual en C y en C++, pero C++ añade un modo adicional de pasar una dirección a una función. Se trata del paso-por-referencia y existe en otros muchos lenguajes, de modo que no es una invención de C++.
La primera impresión que dan las referencias es que no son
necesarias, que se pueden escribir cualquier programa sin
referencias. En general, eso es verdad, con la excepción de unos
pocos casos importantes que se tratarán más adelante en el
libro, pero la idea básica es la misma que la demostración
anterior con el puntero: se puede pasar la dirección de un
argumento utilizando una referencia. La diferencia entre
referencias y punteros es que invocar a una
función que recibe referencias es mas limpio, sintácticamente,
que llamar a una función que recibe punteros (y es exactamente
esa diferencia sintáctica la que hace a las referencias
esenciales en ciertas situaciones). Si
PassAddress.cpp
se modifica para utilizar
referencias, se puede ver la diferencia en la llamada a la
función en main()
:
//: C03:PassReference.cpp #include <iostream> using namespace std; void f(int& r) { cout << "r = " << r << endl; cout << "&r = " << &r << endl; r = 5; cout << "r = " << r << endl; } int main() { int x = 47; cout << "x = " << x << endl; cout << "&x = " << &x << endl; f(x); // Looks like pass-by-value, // is actually pass by reference cout << "x = " << x << endl; } ///:~
Listado 3.17. C03/PassReference.cpp
En la lista de argumentos de f()
, en lugar
de escribir int*
para pasar un puntero, se escribe
int&
para pasar una referencia. Dentro de
f()
, si dice simplemente
r
(lo que produciría la dirección si
r
fuese un puntero) se obtiene el
valor en la variable que r
está
referenciando. Si se asigna a r
,
en realidad se está asignado a la variable a la que que
r
referencia. De hecho, la única manera de
obtener la dirección que contiene r
es con el
operador &
.
En main()
, se puede ver el efecto clave de
las referencias en la sintaxis de la llamada a
f()
, que es simplemente
f(x)
. Aunque eso parece un paso-por-valor
ordinario, el efecto de la referencia es que en realidad toma la
dirección y la pasa, en lugar de hacer una copia del valor. La
salida es:
x = 47 &x = 0065FE00 r = 47 &r = 0065FE00 r = 5 x = 5
De manera que se puede ver que un paso-por-referencia permite a una función modificar el objeto externo, al igual que al pasar un puntero (también se puede observar que la referencia esconde el hecho de que se está pasando una dirección; esto se verá más adelante en el libro). Gracias a esta pequeña introducción se puede asumir que las referencias son sólo un modo sintácticamente distinto (a veces referido como «azúcar sintáctico») para conseguir lo mismo que los punteros: permitir a las funciones cambiar los objetos externos.