2011-09-29 8 views
7

¿Hay algún caso de uso razonable, donde se debe usar const puntero sobre la referencia?Elegir entre la referencia (T &) y el puntero const (T * const)

T obj; 
T &r = obj; // style-1 
T* const p = &obj; // style-2 

Tanto el estilo se puede utilizar para el mismo propósito. Siempre prefiero el primer estilo en el código y considero el estilo posterior como obsoleto. Sin embargo, todavía me pregunto si se perdió algún caso de uso en el que el segundo estilo sea mejor.

Editar: No es limitante para el ejemplo anterior, hablo en un sentido más amplio,

void foo (T& r); // style-1 
void foo (T* const p); // style-2 

[Veo en algunas de las respuestas que, estilo-2 permite pasar nulo.]

+0

¿Para qué? Sé que este código es ilustrativo de la sintaxis que está preguntando, pero ¿en qué escenario de código real se está preguntando? –

+0

Para las funciones, la constitud del argumento de copia es un detalle de implementación irrelevante. –

Respuesta

5

Un const puntero (T* const) puede ser NULL, y que puede ser útil cuando pasar argumentos a una función o al devolver valores desde una función. Por ejemplo, si tiene una función de búsqueda, le recomendamos que devuelva NULL si no encuentra nada. No puede hacer eso si devuelve un tipo de referencia.

1

Para argumentos de funciones, prefiero los punteros a las referencias, porque puedo decir en el sitio de la llamada que el parámetro es un parámetro de salida. Si el argumento de la función es una referencia constante, entonces prefiero las referencias.

La otra gran diferencia es r no puede ser nulo, por lo que si necesita que sea, necesita estilo-2

+0

No importa; la interfaz móvil no parece ser compatible con la eliminación de comentarios. –

2

Déjame salir de una extremidad aquí. Como dice explícitamente "const pointer", asumo que es y no hablando de argumentos de función o incluso valores de retorno de función. Para un argumento de la función aprobada por copia, el constness es un detalle de implementación irrelevante:

void foo(T *);   // declaration 

void foo(T * const pt) // implementation, 
{ /* ... */ }   // pt is const inside the body (who cares?) 

Por lo tanto, el único caso de uso que viene a la mente es si es necesario crear un alias en algún lugar dentro de su propio código. En ese caso, siempre preferiría la referencia. Compare:

for (auto it = box.begin(); it != box.end(); ++it) 
{ 
    T & trinket = *it;  // nice 
    T * const ptr = &*it; // wtpf? 

    // ... 
} 

Desde que ha editado su pregunta: Es evidente que hay una diferencia para los argumentos de la función.

void foo(T &); 
void bar(T *); 

En foo que están garantizados para tener una, referencia de objeto mutable viable; en bar debe comprobar si el puntero no es nulo (lo que le da la noción de un argumento opcional). En ese sentido, T& y T* no son realmente comparables.

+0

Puede ser que lo hayan entendido mal. 'T &' (no 'const T &') y 'T * const' (no' T * ') son muy comparables. Son casi iguales, excepto la firma y el hecho de que el puntero se puede pasar nulo (como se sugiere en algunas respuestas). – iammilind

+0

Lo sé. Pero 'T &' y 'T *' no lo son. Y para las llamadas a funciones, no existe tal cosa como 'T * const'. –

0

1) Al utilizar la referencia, el objeto debe almacenarse en una variable. Por ejemplo, no se puede hacer esto:

void funct (T &); 
funct (T ("Calling constructor")); 

que hacer:

void funct (T &); 
T obj ("Calling constructor"); 
funct (obj); 

2) Cuando se utiliza de referencia, no se puede probar su valor (por ejemplo.compruebe si es NULL, que se usa comúnmente)

Por todo lo demás, es lo mismo.

Generalmente los uso solo si es importante que se llame a la función con una variable verdadera como argumento. Puede que esté pasado de moda, pero el modo de puntero es mejor para mí en todos los demás casos.

+0

En su caso (1) es una variable temporal y en realidad es bueno que no podamos almacenarla como referencia. – iammilind

Cuestiones relacionadas