Compare las siguientes dos piezas de código, la primera utilizando una referencia a un objeto grande, y la segunda tiene el objeto grande como valor de retorno. El énfasis en un "objeto grande" se refiere al hecho de que las copias repetidas del objeto, innecesariamente, son ciclos desperdiciados.Devolución de objetos grandes en funciones
Usando una referencia a un objeto grande:
void getObjData(LargeObj& a)
{
a.reset() ;
a.fillWithData() ;
}
int main()
{
LargeObj a ;
getObjData(a) ;
}
Utilizando el objeto grande como valor de retorno:
LargeObj getObjData()
{
LargeObj a ;
a.fillWithData() ;
return a ;
}
int main()
{
LargeObj a = getObjData() ;
}
El primer fragmento de código no exige que la copia del objeto grande.
En el segundo fragmento, el objeto se crea dentro de la función y, por lo tanto, en general, se necesita una copia al devolver el objeto. En este caso, sin embargo, en main()
el objeto se está declarando. ¿El compilador creará primero un objeto construido por defecto, luego copiará el objeto devuelto por getObjData()
, o será tan eficiente como el primer fragmento?
Creo que el segundo fragmento es más fácil de leer, pero me temo que es menos eficiente.
Edit: Normalmente, estoy pensando en los casos LargeObj
como clases de contenedor genérico que, por el bien de la discusión, contiene miles de objetos dentro de ellos. Por ejemplo,
typedef std::vector<HugeObj> LargeObj ;
tan modificación directa/adición de métodos para LargeObj
no es una solución directamente accesible.
Gracias por la gran explicación y el código para "probar" la optimización del valor de retorno. Puedo confirmar que el compilador de Microsoft Visual Studio 2008 arroja el mismo resultado que g ++, es decir, el conjunto optimizado de operaciones. – swongu
Creo que Visual Studio solo habilitará RVO en/O2 o superior (por ejemplo, no en código de depuración y no solo en/O). – Bklyn
Lo comprobé con VS2008, y descubrí que/Od (desactivado) llama a X :: X() y X :: X (X const &), mientras que/O1/O2/Ox solo llama a X :: X(). Entonces, con la optimización desactivada, la copia se realiza cuando se devuelve fuera de f(). – swongu