2010-05-12 17 views
15

¿Es válido almacenar el valor de retorno de un objeto en una referencia?Almacenar el valor de retorno de la función en la referencia C++

class A { ... }; 
A myFunction() 
{ 
    A myObject; 
    return myObject; 
} //myObject goes out of scope here 

void mySecondFunction() 
{ 
    A& mySecondObject = myFunction(); 
} 

¿Es posible hacer esto con el fin de evitar copiar myObject a mySecondObject? myObject ya no es necesario y debería ser exactamente igual que mySecondObject, por lo que en teoría sería más rápido simplemente para pasar la propiedad del objeto de un objeto a otro. (Esto también es posible mediante el impulso del puntero compartido, pero eso tiene la sobrecarga del puntero compartido.)

Gracias de antemano.

Respuesta

19

No está permitido vincular la referencia temporal a una referencia no constante, pero si hace su const de referencia extenderá la vida útil del temporal a la referencia, consulte this Danny Kalev post about it.

En resumen:

const A& mySecondObject = myFunction(); 
+1

¿Por casualidad sabe por qué esto no está permitido? – Mehrdad

+0

No estoy seguro, pero supongo que la razón es que permitir una referencia no const significaría que el compilador debería determinar cuándo se reasignará la referencia. Considero que esto normalmente se considera parte del análisis de alcance dinámico y no se usa en el estándar de C++. En el caso de const, por otro lado, solo la vida estática de la referencia necesita ser determinada. Este análisis probablemente ya sea necesario en otros casos y, por lo tanto, se consideró aceptable. –

+0

También se puede observar que esta es una función de seguimiento de puntero bastante simple, y que uno podría imaginar un sistema más avanzado. Pero, en general, creo que C++ quiere evitar ese problema y delegarlo al programador. Para eso están los indicadores inteligentes. –

3

Es posible con una referencia constante.

myFunction devuelve por valor, por lo que el valor de retorno es un objeto temporal. Puede vincular una referencia temporal a una constante, y la vida útil del temporal se extiende a la duración de la referencia. No puede vincular una referencia temporal a una referencia no constante (desafortunadamente).

El valor de retorno de myFunction podría ser una copia de myObject. En el lado positivo, copiar elision elision (también conocido como "optimización del valor de retorno denominado" en este caso) permite al compilador construir myObject directamente en el temporal que es el valor de retorno de myFunction, presumiblemente ubicado en algún lugar de la pila del código de llamada. Si lo hace, cuando myObject se sale del alcance, el objeto no se destruye realmente. La optimización se implementa comúnmente; por ejemplo, GCC (¿por lo general?) Lo hace incluso sin indicadores de optimización.

Copia ctor elisión también permite que el compilador para evitar toda copia si lo hizo:

A mySecondObject = myFunction(); 

Esto requiere la aplicación de ambos tipos legales de copia elisión ctor: (1) que devuelve un valor con nombre de una función, y (2) inicializar un objeto desde un temporal.

5

Puede que le interese el return-by-value optimization que hacen muchos compiladores para evitar llamar al constructor de copias.

+0

Esta es una de esas ideas que estoy buscando. No puedo visitar la página pero creo que https://en.wikipedia.org/wiki/Copy_elision#Return_value_optimization sería similar. – konsolebox

Cuestiones relacionadas