2010-03-04 14 views
28

En una función de C++ como esto:En C++, ¿qué significa y significa después del tipo de devolución de una función?

int& getNumber(); 

¿qué significa la &? ¿Es diferente de:

int getNumber(); 
+4

La '' Y, básicamente, establece que estoy devolviendo la dirección ** ** donde se almacena el valor devuelto (es decir, devuelve la 'referencia' del entero) mientras que' int getNumber() 'devuelve el' valor' del entero devuelto por la función. Una cosa es que si el entero de referencia apunta a un NULO, puede tener un error de segmentación mientras que la otra función devuelve un 0; –

+6

Una cosa que nadie mencionó: ¡nunca devuelva una referencia a una variable local! Obtendrá resultados indefinidos cuando la variable salga del alcance al final de la función. –

+4

Como un aparte, si 'getNumber()' es un método público de una clase que devuelve una variable miembro privada de esa clase, no use la versión que devuelve una referencia. De lo contrario, los usuarios de su clase podrán cambiar el valor de ese miembro privado fuera de la clase. En otras palabras, el miembro privado ya no está encapsulado por la clase. –

Respuesta

24

Sí, la versión int& devuelve una referencia a un int. La versión int devuelve un valor int.

Ver the section on references en el ++ FAQ C

+1

¿A quién se le debe bajar la atención? –

+23

En lugar de hacer que el OP lea un enorme documento que responde a su pregunta, pero solo de una manera indirecta, ¿por qué no escribir un programa de 10 líneas que demuestre la diferencia? –

2

"&" medios de referencia, en este caso "referencia a un int".

7

Sí, es diferente.

El & significa que devuelve una referencia. De lo contrario, devolverá una copia (bueno, a veces el compilador lo optimiza, pero ese no es el problema aquí).

Un ejemplo es vector. El operador [] devuelve un &. Esto nos permite hacer:

my_vector[2] = 42; 

Eso no funcionaría con una copia.

+1

+1 para un ejemplo razonable que no usa variables globales! @Johan, no funcionaría porque asignarías a una ubicación de la pila o una copia de la ubicación en el vector ... –

2

Significa que es un tipo de referencia. ¿Qué es una referencia?

Wikipedia:

En el lenguaje de programación C++, una referencia es un simple tipo de datos de referencia que es menos potente pero más seguro que el tipo de puntero heredado de C. El nombre de C++ de referencia puede causar confusión, como en el ordenador science a reference es un tipo de datos de concepto general, con punteros y referencias de C++ que son implementaciones de tipos de datos de referencia específicos. La declaración de la forma:

Tipo & Nombre

donde es un tipo y es un identificador cuyo tipo es la referencia a .

Ejemplos:

  1. int A = 5;
  2. int & rA = A;
  3. extern int & rB;
  4. int & foo();
  5. barra de vacíos (int & rP);
  6. clase MyClass {int & m_b;/* ...* /};
  7. int funcX() {return 42; }; int (& xFunc)() = funcX;

Aquí, Ra y Rb son de tipo "referencia a int", foo() es una función que devuelve una referencia a int, bar() es una función con un parámetro de referencia, que es referencia a int, MyClass es una clase con un miembro que es referencia a int, funcX() es una función que devuelve un int, xFunc() es un alias para funcX.

resto de la explicación es here

+1

desafortunadamente la wikipedia está mal aquí. No es más seguro que un puntero, es exactamente azúcar sintáctica para un puntero de const (NO me refiero al puntero para obtener datos). –

+2

Pero puede evitar muchos errores del compilador. Esto es lo que significa wikipedia. – Shayan

+1

Nunca he oído hablar de un solo error de compilación que era fundamentalmente diferente para los punteros y las referencias. –

1

Significa que está devolviendo un reference a un int, no un int sí.

1

Es una referencia, que es exactamente como un puntero, excepto que no tiene que usar un operador de desreferencia de puntero (* o ->) con él, la desreferenciación del puntero es implícita.

Tenga en cuenta especialmente que todas las preocupaciones de por vida (tales como no devolver una variable de pila por dirección) todavía deben abordarse como si se utilizara un puntero.

+1

Las referencias se pueden comparar con punteros, y se consideran punteros, pero definitivamente no son "exactamente como punteros". Por ejemplo, la asignación a una referencia cambia el valor * referido a *, en lugar de la referencia en sí misma. Además, a las referencias se les debe asignar un valor en el momento de su creación, y seguir refiriéndose a ese mismo valor durante toda su vida útil. – Thomas

+1

@Thomas: a las referencias no se les asigna un valor en la creación, están asociadas con una dirección, un puntero. Sí, no se pueden reasociar con una nueva dirección, pero tampoco se puede asociar con un puntero. La asignación a través de una referencia es exactamente lo mismo que la asignación a través de un puntero, excepto que necesita un asterisco adicional para la sintaxis del puntero, eso es lo que quise decir con "desreferenciación del puntero". Una referencia no es más y no es menos que un puntero de const mezclado con un poco de azúcar sintáctico. –

4

int& getNumber(): function devuelve un número entero por referencia.

int getNumber(): la función devuelve un número entero por valor.

Se diferencian de alguna manera y una de las diferencias interesantes es que el primer tipo se puede usar en el lado izquierdo de la asignación, lo cual no es posible con el segundo tipo.

Ejemplo:

int global = 1; 

int& getNumber() { 
     return global; // return global by reference. 
} 

int main() { 

     cout<<"before "<<global<<endl; 
     getNumber() = 2; // assign 2 to the return value which is reference. 
     cout<<"after "<<global<<endl; 

     return 0; 
} 

Ouptput:

before 1 
after 2 
4

La primera versión le permite escribir , que probablemente no es lo que desea. La devolución de referencias es muy útil cuando se sobrecarga operator[] para sus propios tipos de contenedores. Le permite escribir container[9] = 42.

+1

Explique por qué funciona para contenedores y tiene una respuesta perfecta. –

25

Es diferente.

int g_test = 0; 

int& getNumberReference() 
{ 
    return g_test; 
} 

int getNumberValue() 
{ 
    return g_test; 
} 

int main() 
{ 
    int& n = getNumberReference(); 
    int m = getNumberValue(); 
    n = 10; 
    cout << g_test << endl; // prints 10 
    g_test = 0; 
    m = 10; 
    cout << g_test << endl; // prints 0 
    return 0; 
} 

la getNumberReference() devuelve una referencia, bajo el capó es como un puntero que apunta a una variable de número entero. Cualquier cambio aplicado a la referencia se aplica a la variable devuelta.

El getNumberReference() es también una izquierda-valor, por lo tanto, se puede utilizar la siguiente manera:

getNumberReference() = 10; 
5

La diferencia es que sin el & lo que recibe es una copia de la int devuelto, adecuada para pasar a otras rutinas, comparar cosas o copiar en su propia variable.

Con el &, lo que obtiene es esencialmente la variable que contiene el entero devuelto.Eso significa en realidad se puede poner en el lado izquierdo de una asignación, así:

getNumber() = 200; 
Cuestiones relacionadas