Tutorial de C++ - Referencias

10 - Referencias

[editar]
Tutorial creado por Peter Class; traducción por Pello Xabier Altadill Izura. Extraido de: http://es.tldp.org/Manuales-LuCAS/doc-tutorial-c++/html/
28 de Febrero de 2006
Una referencia es otra forma de acceder a un dato, una especie de alias. Cualquier operacion sobre una referencia afectara a ese dato al que hace referencia.

Figura: sin duda los punteros y las referencias fueron obra de los sarracenos.

Veamos un ejemplo simple:

/**
 * Referencias.cpp
 * Programa que muestra el uso de referencias
 * 
 * Pello Xabier Altadill Izura 
 *
 * Compilado: g++ Referencias.cpp -o Referencias
 */
 
 using namespace std;
 #include <iostream>
 
 int main() {
 
  // Definimos un dato y su referencia
  int numero;
  int &referenciaNumero = numero; // Ahi se crea la referencia
  
  cout << "Vamos a ver que pasa si le asignamos un dato: " << endl;
 
  numero = 31337;
  
  // Los dos mostraran el mismo valor
  cout << "Valor de numero: " << numero << endl;
  cout << "Valor de referenciaNumero: " << referenciaNumero << endl;
  
  // y a donde apuntan? AL MISMO SITIO
  cout << "Posicion de numero: " << &numero << endl;
  cout << "Posicion de referenciaNumero: " << &referenciaNumero << endl;
  cout << "Programa terminado \n" << endl;
  
  return 0;
 
 }

Con los objetos se pueden hacer referencias igualmente:

Objeto miObjeto;
 Objeto &refObjeto = miObjeto;

Referencias y funciones Vamos a ver distintas formas de pasar referencias a una funcion. Como en c, podemos pasar parametros por referencia y hacer que esos parametros contengan resultados de una funcion.

/**
 * ReferenciaFunciones.cpp
 * Programa que muestra el uso de referencias en las funciones
 * 
 * Pello Xabier Altadill Izura 
 *
 * Compilado: g++ ReferenciaFunciones.cpp -o ReferenciaFunciones
 */
 
 using namespace std;
 #include <iostream>
 
 // 1º funcion que intercambia dos valores
 void exchange (int *refa, int *refb);
 
 // 2º funcion -sobrecargada- que intercambia dos valores
 void exchange (int &refa, int &refb);
 
 
 int main() {
  
  // Definimos un dato y su referencia
  int a, b;
  
  cout << "Asignamos valores: " << endl;
  a = 45;
  b = 21;
  
  cout << "Valores: a=" << a << " b=" << b << endl;
  cout << "Hacemos intercambio con exchange(int *refa, int *refb): " << endl;
 
  exchange(&a, &b); // Con esta llamada invocamos la primera funcion!!
  
  cout << "Valores: a=" << a << " b=" << b << endl;
  cout << "Hacemos intercambio con exchange(int &refa, int &refb): " << endl;
 
  xchange(a, b); // Con esta llamada invocamos la segunda funcion!!
  
  out << "Valores: a=" << a << " b=" << b << endl;
  out << "Programa terminado \n" << endl;
 
  return 0;
 
 }
 
 // 1º funcion que intercambia dos valores
 void exchange (int *refa, int *refb) {
 
  int tmp;
 
  tmp = *refa;
  *refa = *refb;
  *refa = tmp; 
 
 }
 
 
 // 2º funcion -sobrecargada- que intercambia dos valores
 void exchange (int &refa, int &refb) {
  
  int tmp;
  
  tmp = refa;
  refa = refb;
  refa = tmp;
 
 }
 

Pasando clases por referencia

/**
 * Gremlin.hpp
 *
 * Clase que representa el objeto Gremlin.
 * Observese el 3º metodo constructor
 * Pello Xabier Altadill Izura 
 *
 */
 
 using namespace std;
 #include <iostream>
 
 class Gremlin {
 
 public:
 
  Gremlin();
 
  Gremlin(char *nmb,int ed, int p);
  
  Gremlin(Gremlin&); // atencion a este constructor
  
  ~Gremlin();
 
  void correr();
 
  void dormir();
 
  void morder();
 
  int peso;
 
 private:
  
  char *nombre;
  
  int edad;
 
 };

Y su implementacion:

/**
 * Gremlin.cpp
 *
 * Clase que implementa el objeto Gremlin.
 * Pello Xabier Altadill Izura 
 *
 */
 
 #include "Gremlin.hpp"
 
 Gremlin::Gremlin() {
 
  peso = 1;
 
  cout << "Gremlin creado." << endl;
 
 }
 
 
 Gremlin::Gremlin (char *nmb,int ed, int p) {
  
  nombre = nmb;
  edad = ed;
  peso = p;
 }
 
 
 Gremlin::~Gremlin() {
  
  cout << "Aaaargh!\nGremlin destruido." << endl;
 
 }
 
 
 
 // El gremlin corre
 void correr() {
  
  cout << "Jaja grrrr!! jajaja!" << endl;
 
 }
 
 
 // El gremlin duerme
 void dormir() {
 
  cout << "zzzZZZZzzzzz" << endl;
 
 }
 
 
 // El gremlin muerde
 void morder() {
 
  cout << "roaar &ntilde;am &ntilde;am" << endl; 
 
 }
 
 
 // Definimos esta funcion aparte de la clase
 // Con ella el gremlin come y aumenta su atributo peso.
 void comer (Gremlin *g) {
 
  // Invocamos la mordedura para que coma
  g->morder();
 
  // Le aumentamos 3 unidades por comer
  g->peso += 3;
 
 }
 
 
 // Funcion main
 int main () {
 
  cout << "Iniciando programa. " << endl;
  
  // Definimos un gremlin
  Gremlin tbautista;
 
  // y lo movemos por la ciudad
  tbautista.correr();
  tbautista.morder();
 
  // Mostramos su peso
  cout << "El gremlin pesa: " << tbautista.peso << endl;
 
  // Le hacemos comer:
  comer(&tbautista);
 
  // Mostramos su peso otra vez
  cout << "El gremlin pesa ahora: " << tbautista.peso << endl;
  cout << "Finalizando programa\n " << endl;
 
  return 0;
 
 }

La ventaja que logramos al pasar parametros por referencia es que ahorramos espacio en memoria ya que sino en cada llamada a una funcion se hacen copias de los parametros. Esto tambien tiene una desventaja: si le pasamos a una funcion el ORIGINAL de un objeto (con una referencia) en lugar de una copia corremos el riesgo de que la funciona haga trizas nuestro objeto y perder el "original" (supongamos que la funcion esta hecha por terceros y no sabemos lo que hace). Que se puede hacer para salvaguardar nuestros objetos? Punteros constantes Esta es la solucion: pasar punteros constantes. Eso hara que la funcion solo tenga permiso para invocar los metodos constantes de la clase. SE cambia un poco la clase gremlin para mostrar esto.

/**
 * Gremlin2.hpp
 *
 * Clase que representa el objeto Gremlin.
 * Con un metodo definido como const!!
 * Pello Xabier Altadill Izura 
 *
 */
 
 using namespace std;
 #include <iostream>
 
 class Gremlin {
 
 public:
 
  Gremlin();
 
  Gremlin(char *nmb,int ed, int p);
 
  Gremlin(Gremlin&); // atencion a este constructor
 
  ~Gremlin();
 
  void correr();
 
  void dormir();
 
  void morder();
 
  // Definimos una funcion constante
  char * getNombre() const;
 
  int peso;
 
 private:
  
  char *nombre;
  
  int edad;
 
 };

Y vemos la implementacion en la que simplemente se puede observar como se protege el objeto en la funcion comer() gracias al uso de punteros constantes.

/**
 * Gremlin2.cpp
 *
 * Clase que implementa el objeto Gremlin.
 * Pello Xabier Altadill Izura 
 *
 */
 
 #include "Gremlin2.hpp"
 
 Gremlin::Gremlin() {
  
  peso = 1;
  
  cout << "Gremlin creado." << endl;
 
 }
 
 
 Gremlin::Gremlin (char *nmb,int ed, int p) {
  
   nombre = nmb;
   edad = ed;
   peso = p;
 
 }
 
 
 Gremlin::~Gremlin() {
  
  cout << "Aaaargh!\nGremlin destruido." << endl;
 
 }
 
 
 // El gremlin corre
 void correr() {
  
  cout << "Jaja grrrr!! jajaja!" << endl;
 
 }
 
 
 // El gremlin duerme
 void dormir() {
  
  cout << "zzzZZZZzzzzz" << endl;
 
 }
 
 
 // El gremlin muerde
 void morder() {
  
   cout << "roaar &ntilde;am &ntilde;am" << endl; 
 
 }
 
 
 // FUNCION CONST!!!
 // Devuelve el nombre del gremlin
 char * getNombre() const {
 
   return nombre;
 
 }
 
 
 // Definimos esta funcion aparte de la clase
 // Con ella el gremlin come y aumenta su atributo peso.
 void comer (const Gremlin const *g) {
 
  // Invocamos la mordedura para que coma??
  // g->morder(); ERROR no podemos invocar una funcion NO CONSTANTE!!!
  // en cambio si podemos invocar getNombre
  cout << "Nombre" << g->getNombre() << endl; 
 
 }
 
 
 // Funcion main
 int main () {
 
  cout << "Iniciando programa. " << endl;
 
  // Definimos un gremlin
  Gremlin tbautista;
  
  // y lo movemos por la ciudad
  tbautista.correr();
  tbautista.morder();
  
  // Mostramos su peso
  cout << "El gremlin pesa: " << tbautista.peso << endl;
 
  // Le hacemos comer:
  comer(&tbautista);
  
  // Mostramos su peso otra vez
  cout << "El gremlin pesa ahora: " << tbautista.peso << endl;
  cout << "Finalizando programa\n " << endl;
 
  return 0;
 
 }
[editar]

23 opiniones

yery cruz

12345
DamiaN

Mal exlicado :S,
no dice nada

agan algo de servicio por favor no mas estupidos
alegoria

cuando uno va a esplicar de progamacion primero se esplican los concepto, delas intrucciones,para que el estudiante sepa lo que se dice o de lo que se esta hablando, si es que esta pagina intructiva, sinoo no pongan estos ejemplo pues son tan astracto para los principiates que lo que hacen es asustarlos y seban , para esto de maestro, hay que ser humilde yno creer que como ya yo se no me importa lo que venga, no tomen esto, como algo mejoren, mejoren,mejoren, los quiero mucho migel.
Sobre nombre de array.

Hola, peter. Respecto a tu primera pregunta sobre cómo nombrar lo que en el código aparece como "array" en inglés, te puedo decir que no es correcta ninguna de las dos opciones que ofreces. Si se usa "arrays" se está españolizando la palabra inglesa "array". No muy conveniente, porque en español ya existe la palabra adecuada para ese concepto: "vector". De todos modos, españolizar una palabra inglesa en argot técnico no es tan grave como usar la palabra española traducida según una acepción inglesa incorrecta. Nunca se debería usar "arreglo".
1 2 3 4 5 | siguiente >

Tutoriales relacionados con 'Tutorial de C++'

Este es el diario de Peter Class sobre sus dias aprendizaje de una disciplina de... Más »
Este tutorial presenta los conceptos básicos de líneas de transmisión (Transmission lines), así como una... Más »
Si tuviera que buscar un adjetivo para calificar a Sendmail, pensaría en "excesivo". Excesivo puesto... Más »
La red telefónica básica se creó para permitir las comunicaciones de voz a distancia. Esto... Más »
Bienvenidos al manual de HTML de Indaya.A través de todos estos capítulos vamos a descubrir... Más »

Autor y licencia de 'Tutorial de C++'


Tutorial de Peter Class; traducción por Pello Xabier Altadill Izura. Extraido de: http://es.tldp.org/Manuales-LuCAS/doc-tutorial-c++/html/ CopyLeft
Este documento se cede al dominio publico.
Este contenido ha sido recopilado por el equipo de Wikilearning. Todo el contenido recopilado se ha obtenido respetando y comunicando en nuestro site la licencia de cada fuente.
Wikilearning tiene permiso expreso por escrito de los autores para publicar los contenidos que ha extraído de otras webs, incluyendo su uso comercial.