c++ - pass - Parámetros de función: ¿Copia o puntero?
pointer to function c language (6)
Evite el uso de puntero.Utilice la referencia constante si el parámetro IN es más que una referencia para el parámetro IN OUT
Soy un poco nuevo en C ++ y tengo algunas preguntas, esta es una de ellas.
¿Hay CUALQUIER razón cuando está utilizando una función que toma en uno o varios parámetros, cuyos parámetros sabe que siempre se almacenarán en una variable antes de la llamada a la función, para pasar una copia de la variable, en lugar de un puntero a la variable ?
Estoy hablando en términos de rendimiento. Me parece que tomaría muchos más recursos pasar una copia de una estructura completa que solo un puntero (4 bytes).
Hay varias formas en que pasar una copia puede ser más barato que pasar un puntero.
- El objeto es igual o más pequeño que un puntero. El acceso directo a un valor siempre será más rápido que desmarcando un puntero.
- La estructura es lo suficientemente pequeña como para ser puesta en la pila por el compilador. En este caso, el acceso a los valores en la estructura se realiza mediante modos de direccionamiento indexados en lugar de modos de direccionamiento indexados indirectos. Los primeros son generalmente más rápidos.
Hay otras razones para querer pasar una copia en lugar de una referencia, es decir, su función hará cambios en la estructura que no se reflejarán de nuevo a la persona que llama. Si bien esto generalmente es una práctica deficiente, hacer que el parámetro pase por valor asegurará que la vista de la persona que llama no se modifique de forma incorrecta.
Ahora, para la parte de la respuesta que probablemente no quieras escuchar: ¡Generalmente no hace mucha diferencia! Use el método de paso de parámetros que tenga más sentido para la semántica de su programa. Si luego descubre que hay un cuello de botella de rendimiento en un área en particular, entonces concéntrese en mejorar el rendimiento allí. No más de optimizar!
La pregunta principal no es sobre el rendimiento, sino la semántica, y si su función modifica los datos en la estructura.
Si su función modifica la estructura, pasar un puntero permitirá que la persona que llama vea los datos modificados en la estructura. En este caso, pasar una copia probablemente sea incorrecto, ya que su función modificará una copia que luego (presumiblemente) se descartará. Por supuesto, es posible que su función modifique los datos, pero no desea las modificaciones, en cuyo caso una copia es lo correcto, para proteger los valores originales de los cambios.
Si su función no modifica la estructura, entonces no hay razón para copiar los valores, ya que solo se leerán.
Si no se siente cómodo con el concepto de pasar punteros a las estructuras, debe obtener algo de práctica, porque es la forma típica de tratar con estructuras en C y C ++.
En lo que respecta al rendimiento, es más trabajo copiar la estructura, pero es bastante menor en el esquema de las cosas. Primero, concéntrate en la semántica del código.
Un puntero se abre para los errores, ya que le permite al destinatario alterar el objeto. Los punteros pueden ser 0, lo que tiende a crear bloqueos, y esto crea la necesidad de probar 0 punteros por todas partes, esto puede ser molesto. Al usar referencias de C ++, const
-declared donde sea posible, elude estos dos problemas.
una referencia es más común, o una referencia constante si no van a cambiar.
Pasar un objeto por puntero (o referencia) y pasar una copia del mismo objeto tiene una semántica diferente. Si desea realizar cambios en un objeto que se reflejará fuera de la llamada de función, quiere semántica de referencia; de lo contrario, desea semántica de valores.
Comúnmente, la semántica de valores se puede expresar pasando el valor por valor o por referencia constante
void value_semantics(my_obj obj);
void value_semantics(const my_obj& obj);
Sin embargo, la forma de referencia de referencia también tiene algunos inconvenientes, previene varias optimizaciones que el compilador puede hacer debido a problemas de aliasing también para objetos con constructores triviales. El nivel extra de indirección (una referencia se implementa como un puntero) puede compensar los beneficios de evitar la copia.
Para obtener semántica de referencia puede elegir pasar por referencia o por puntero, ya que otras referencias ya dichas son más naturales que punteros en C ++ (no es necesario usar la dirección del operador &
) y la única ventaja real de punteros es si quieres habilitar valores NULL.
La regla de oro es que para las clases no triviales debe pasar por la referencia constante, de lo contrario por valor.