c++ - retornan - pasar una estructura como parametro en c
¿Las pequeñas estructuras simples deben pasarse por referencia constante? (6)
Mi idea es que al pasar el Vector2 por referencia, en realidad es más costoso que pasar por valor, ya que el compilador ahora está usando un puntero y una referencia para acceder a la versión constante Vector2 y pos.
Sería cierto si pasara un objeto donde size_of(object) < size_of(pointer_to_object)
. Por ejemplo, char const&
podría ser más caro que char
Siempre me han enseñado que los tipos no primitivos deben pasarse por referencia constante en lugar de por valor cuando sea posible, es decir:
void foo(std::string str);//bad
void foo(const std::string &str);//good
Pero hoy pensé que tal vez en realidad algunos tipos simples definidos por el usuario podrían pasar mejor por valor, por ejemplo:
class Vector2
{
public:
float x, y;
...constructors, operators overloads, utility methods, etc...
};
void foo(Vector2 pos);
void foo(const Vector2 &pos);//is this really better than by value?
void foo(float x, float y);//after all isn''t by value effectively doing this?
Mi idea es que al pasar el Vector2 por referencia, en realidad es más caro que pasar por valor, ya que el compilador ahora está usando un puntero y una desreferenciación para acceder a la versión const Vector2 y pos.
¿Es este el caso? ¿Los objetos simples se pasan mejor por valor? ¿Dónde debería dibujarse la línea?
Al pasar por una referencia constante se evita la construcción de un nuevo objeto. Si su constructor no es trivial, por ejemplo, asigna memoria, será mejor que pase por referencia constante que por valor.
En el mundo C #, tomas esta decisión al elegir si hacer algo como una clase o una estructura. Las clases usan semántica de referencia, mientras que las estructuras usan semántica de valor. Todo lo que he leído dice que, en general, debería elegir que todo sea una clase a menos que sea muy pequeño, es decir, del orden de 16 bytes. Si está buscando un punto de corte para cuándo pasar por referencia de valor versus const en C ++, 16 bytes parece un umbral razonable.
Sí, los objetos simples deben pasarse por valor. La línea debe trazarse según la arquitectura. En caso de duda, perfil.
Se puede encontrar un análisis anterior, pero lúcido, de las entradas y salidas de los parámetros de aprobación en http://www.ddj.com/184403855 . Por supuesto, c ++ 0x obvia muchos de estos problemas con la semántica de movimiento, pero el documento proporciona una gran cantidad de justificación de por qué es deseable la semántica de movimiento.
Solo como una cuestión de política, paso cualquier objeto que no sea un tipo de datos C básico por referencia constante. Es mucho más fácil de recordar de esa manera.
Un factor que no he visto mencionado es lo que la rutina va a hacer con el valor pasado. A menos que la rutina se expanda en línea, la manipulación de los datos que se pasan por referencia requerirá más código que la manipulación de los datos que se pasan por valor. Si en promedio se accederá a los campos de la estructura pasada menos de una vez, esta sobrecarga adicional será pequeña en comparación con la sobrecarga de copiar la estructura. Si, en promedio, se accederá a ellos muchas veces, es mejor tenerlos en la pila. Si la interfaz ya está configurada como paso por referencia para una estructura a la que se accede con frecuencia, puede tener sentido que la rutina llamada copie todas las partes que sean de interés. Por otro lado, si la rutina llamada va a copiar gran parte o la totalidad de una estructura de todos modos, también puede pasarse por valor.