2009-04-14 13 views

Respuesta

20

La versión & representa una referencia, mientras que la versión * representa un puntero. La diferencia es demasiado grande para una publicación SO típica. Le sugiero que comience en el C++ FAQ Lite

http://www.parashift.com/c++-faq-lite/references.html

Por lo general no me gusta para responder a mensajes con una respuesta "que puedes usar Google". Sin embargo, este es un tema que recomiendo encarecidamente a google. En particular, google "punteros C++ vs. referencias". Hay una gran cantidad de información disponible sobre este tema y las discusiones en esas páginas prevalecerán sobre cualquier cosa que escribamos aquí.

+1

Creo que Joel y Jeff estarían encantados de que cualquier persona que use Google para responder a esta pregunta sea dirigida a una página de StackOverflow e impresionado por un anunciante de StackOverflow. –

+3

Sí, sé que esto es viejo. Pero llegué a esta página después de una búsqueda en google de "diferencia entre referencia y puntero". Fue resultado # 3. – Ross

+2

ugh, busqué en Google y vine aquí ... Literalmente es exactamente la misma pregunta que tengo. –

5

Una clase * puede apuntar a cualquier objeto de clase, o ninguna.

Una clase & siempre apunta a exactamente un objeto de clase, y nunca puede apuntar a uno diferente.

Por otra parte, creo que Bjarne es un miembro del conjunto de personas que han afirmado "matrices en C se rompen sin posibilidad de reparación," una clase * puede apuntar a todo un ding-Dang matriz de objetos de clase, se alinearon uno después del otro en la memoria, y no hay absolutamente ninguna manera en C para decir si una Clase * apunta a uno o muchos.

6

El * es un puntero, el & es referencia. La diferencia entre los dos es que un puntero es un área de memoria que debe desreferenciarse, por ejemplo. por medio del operador -> para ser "visto" como una instancia de clase. Una referencia es, en cambio, un "alias", solo un nombre alternativo para la misma instancia de clase. No necesita usar el operador -> con una referencia. Usas el operador de punto.

Personalmente, raramente utilizaba las referencias, sobre todo cuando tenía un objeto de valor que asignaba en la pila. El nuevo operador siempre devuelve un puntero, que luego debe desreferenciar. Además, uno de los problemas más problemáticos de las referencias es que no puede establecerlos en NULL. En algunos casos, es útil tener una función que acepte un puntero de objeto o NULL. Si su función acepta una referencia, no puede pasar un NULO (puede usar el patrón de objeto Nulo, sin embargo)

+0

Por supuesto, los punteros nulos son una gran fuente de errores en C++, así que no creo que las referencias sean malas en ese sentido. –

0

Otra diferencia es que las variables de referencia deben inicializarse. No puede crear una variable de referencia como la que se muestra en el código de muestra. Eso produciría un error de compilación.

0

Una referencia (&) es exactamente lo mismo que un puntero (*), excepto que el compilador C++ garantiza que no sea NULL. Sin embargo, aún puede ser un puntero colgante (una variable de puntero que no tiene ninguna referencia, por lo que es basura y no válida para cualquier uso).

0

Como se ha dicho que debe buscar en Google, pero para evitar malos entendidos:

  • referencias no son variables
  • referencias no son similares a los punteros (pero se pueden utilizar de manera similar)

Piense en una referencia como un acceso directo para el término que se le asigna.

0

Un consejo adicional que iba a ofrecer es la siguiente:

Utilizar referencias cuando se puede, los punteros cuando tiene que hacerlo. Si se garantiza que el objeto existe, probablemente debería usar una referencia. Si no es así, entonces probablemente tenga que usar un puntero.

Una ventaja adicional es que las referencias eliminan la ambigüedad en la propiedad. Tan pronto como un programador de mantenimiento ve un puntero, comenzarán a preguntarse si deberían eliminarlo.

Comprobar a cabo este ejemplo:

 
// Wrapper class using a reference because the wrapped object always exists 
class Wrapper 
{ 
public: 
    // If the wrapped is guaranteed to exist at creation, do it this way 
    Wrapper(Wrapped& wrapped):_wrapped(wrapped) { /* empty */ } 

    // put extra methods here. 
    int getWrappedValue() const { return _wrapped.getValue(); } 

private: 
    Wrapped& _wrapped; // This object always exists and is valid 
}; 

// Wrapper class written to support a possibly non-existent wrapped object. 
class Wrapper 
{ 
public: 
    Wrapper(Wrapped* wrapped = 0):_wrapped(wrapped) { /* empty */ 

    void setWrappee(WRappee* wrapped) { _wrapped = wrapped; } 

    int getWrappedValue() const; // Not making inline -- more complex 

private: 
    Wrapped* _wrapped; // Always check pointer before use 
}; 

int Wrapper::getWrappedValue() const 
{ 
    if (_wrapped) 
    { 
    return _wrapped->getValue(); 
    } 
    else 
    { 
    return -1; // NOTE, this is a contrived example -- not getting into exceptions 
    } 
} 
Cuestiones relacionadas