Pregunta

Supongamos que tengo el siguiente código:

class some_class{};

some_class some_function()
{
    return some_class();
}

Esto parece funcionar bastante bien y me ahorra la molestia de tener que declarar una variable sólo para generar un valor de retorno.Pero no creo haber visto esto nunca en ningún tipo de tutorial o referencia.¿Es esto algo específico del compilador (visual C++)?¿O esto está haciendo algo mal?

¿Fue útil?

Solución

No, esto es perfectamente válido.Esto también será más eficiente ya que el compilador puede optimizar el temporal.

Otros consejos

Devolver objetos de una llamada de función es el patrón de diseño "Factory" y se usa ampliamente.

Sin embargo, deberá tener cuidado al devolver objetos o punteros a objetos.El primero de ellos le presentará los constructores de copia/operadores de asignación, lo que puede resultar complicado.

Es válido, pero el rendimiento puede no ser el ideal dependiendo de cómo se llame.

Por ejemplo:

A a;
a = fn();

y

A a = fn();

no son lo mismo.

En el primer caso, se llama al constructor predeterminado y luego se invoca al operador de asignación en a, lo que requiere que se construya una variable temporal.

En el segundo caso se utiliza el constructor de copias.

Un compilador lo suficientemente inteligente determinará qué optimizaciones son posibles.Pero, si el constructor de copia lo proporciona el usuario, entonces no veo cómo el compilador puede optimizar la variable temporal.Tiene que invocar el constructor de copia y, para ello, debe tener otra instancia.

La diferencia entre el ejemplo de Rob Walker se llama Optimización del valor de retorno (RVO) si desea buscarlo en Google.

Por cierto, si desea asegurarse de que su objeto se devuelva de la manera más eficiente, cree el objeto en el montón (es decir, a través de nuevo) usando un valor compartido_ptr y devuelva un valor compartido_ptr en su lugar.El puntero se devuelve y la referencia cuenta correctamente.

Eso es C++ perfectamente razonable.

Este es C++ perfectamente legal y cualquier compilador debería aceptarlo.¿Qué te hace pensar que podría estar haciendo algo mal?

Esa es la mejor manera de hacerlo si tu clase es bastante liviana; quiero decir, no es muy costoso hacer una copia.

Sin embargo, un efecto secundario de ese método es que tiende a hacer que sea más probable que se creen objetos temporales, aunque eso puede depender de qué tan bien el compilador pueda optimizar las cosas.

Para clases más pesadas que desea asegurarse de que no se copien (digamos, por ejemplo, una imagen de mapa de bits grande), entonces es una buena idea pasar cosas así como un parámetro de referencia que luego se completa, solo para asegurarse absolutamente de que no se crearán ningún objeto temporal.

En general, puede suceder que simplificar la sintaxis y hacer las cosas más directas pueda tener el efecto secundario de crear más objetos temporales en las expresiones, algo que debes tener en cuenta al diseñar interfaces para objetos más pesados.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top