2008-11-04 12 views
8

Soy un poco nuevo en C++ y tengo algunas preguntas, esta es una de ellas.Parámetros de función: ¿Copia o puntero?

¿Hay ALGUNA razón para utilizar una función que toma uno o varios parámetros, cuyos parámetros siempre se guardarán en una variable antes de la llamada a la función, para pasar una copia de la variable, en lugar de una 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).

Respuesta

1

una referencia es más común, o una referencia constante si no van a cambiar.

4

Un puntero se abre para los errores, ya que permite que el destinatario altere 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. El uso de referencias de C++, const -se declara donde sea posible, elude estos dos problemas.

+0

Agregaría que los punteros nulos 0 son aún más molestos. – tloach

+0

¿Qué son los punteros nulos 0? – Motti

+0

int * ohoh = new int; eliminar ohoh; cout << ohoh; // no 0 puntero nulo – MattyT

2

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, al pasar un puntero, la persona que llama verá 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 cuanto 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.

4

Evitar el uso de pointer.Use constante referencia si es EN parámetro demás sólo de referencia para el parámetro IN OUT

12

Hay varias formas en las que pasa una copia puede ser más barato que pasar un puntero.

  1. El objeto es igual o menor que un puntero. El acceso directo a un valor siempre será más rápido que desmarcando un puntero.
  2. La estructura es lo suficientemente pequeña como para ser colocada 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 quiera escuchar: ¡Por lo general, 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!

10

Pasar un objeto por un 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 semántica de valor se pueden expresar ya sea 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 en referencia constante tiene algunas desventajas también, impide que varias optimizaciones que el compilador puede hacer debido aliasing issues también para objetos con constructores triviales el nivel adicional de direccionamiento indirecto (una referencia se implementa como un puntero) puede superar 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 el único la verdadera ventaja de los punteros es si desea habilitar valores NULL.

La regla de oro es que para las clases no triviales debe pasar por referencia constante, de lo contrario por valor.

Cuestiones relacionadas