2010-12-13 18 views
23

¿Pasa el argumento del puntero, pasa por valor en C++? Como veo que cualquier cambio en el puntero como tal no se refleja fuera del método. Sin embargo, se reflejan los cambios que hago desreferenciando el puntero.¿Está pasando el argumento del puntero, pasa por valor en C++?

En ese caso, ¿es aceptable/procedimiento estándar usar el puntero al puntero como argumento para una función para modificar el valor del puntero como tal dentro de una función?

+5

El puntero se pasa por valor, pero el objeto apuntado por el puntero se puede modificar mediante la función (dependiendo de la cualificación de const). – dreamlax

Respuesta

24

Sí a ambos.

Los indicadores se transmiten por valor como cualquier otra cosa. Eso significa que el contenido de la variable de puntero (la dirección del objeto apuntado) se copia. Eso significa que si cambia el valor del puntero en el cuerpo de la función, ese cambio no se reflejará en el puntero externo que aún apuntará al objeto viejo. Pero puede cambiar el valor del objeto al que apunta.

Si desea reflejar los cambios realizados en el puntero al puntero externo (hacer que apunte a otra cosa), necesita dos niveles de indirección (puntero a puntero). Cuando llamas a funciones, lo haces poniendo un & antes del nombre del puntero. Es la forma estándar C de hacer las cosas.

Al usar C++, se prefiere utilizar referencias en lugar de puntero (en adelante también como puntero a puntero).

Para los por qué referencias serán preferibles a los punteros, hay varias razones:

  • referencias introducen ruido menos sintáctica que los punteros en el cuerpo de la función
  • referencias mantienen más información que los punteros, que puede ser útil para el compilador

inconvenientes de las referencias son en su mayoría:

  • rompen la simple regla de paso por valor de C, lo que hace menos comprensible el comportamiento de una función con respecto a los parámetros (¿serán cambiados?). También necesita un prototipo de función para estar seguro. Pero eso no es realmente peor que los niveles de múltiples apuntadores necesarios al usar C.
  • no son compatibles con C, eso puede ser un problema cuando se escribe código que debería funcionar con programas C y C++ (pero eso no es lo más caso habitual).

En el caso específico de puntero a puntero, la diferencia es mayoritariamente simple, pero al usar referencia también puede ser fácil eliminar ambos niveles de punteros y pasar solo una referencia en lugar de un puntero a puntero.

+1

¿Por qué es preferible utilizar punteros para las referencias? – Arafangion

+0

@Arafangion: Edité mi respuesta para explicar por qué las preferencias deberían preferirse a las punteros. – kriss

+0

Supongo que es subjetivo: prefiero usar referencias porque transfiero la responsabilidad de la verificación del puntero nulo a la persona que llama, y ​​normalmente no me importa la compatibilidad con C. Sin embargo, no estoy seguro de que me vendieron "También necesita prototipos de funciones para asegurarse de que el valor no se modifique", eso es cierto para muchas de las clases de C++, podrían ser indicadores por sí mismos y podrían o no compartir datos. Dicho esto, prefiero pasar de valor y dejar que la clase se ocupe de los indicadores si es necesario, a menos que devuelva las referencias de valor que se deben establecer inmediatamente, independientemente, +1 – Arafangion

0

O bien un puntero a un puntero, o una referencia a un puntero, es lo que usaría si quisiera cambiar potencialmente el puntero. Para su pregunta original, técnicamente, sí, todos los parámetros se pasan por valor.

+7

"Todos los parámetros se pasan por valor" No, los argumentos pasados ​​por referencia no se pasan por valor. –

0

Sí lo es, como lo es en C.

En ese caso, es procedimiento aceptable/estándar para usar puntero a puntero como argumento de una función de modificar el valor del puntero como tal dentro de una función ?

¿En qué caso? ¿Qué deseas?Puede usar referencias reales con el modificador &.

void func(type &ref); 
6

Entiendo la confusión aquí. Los conceptos de "pasar por valor" y "pasar por referencia" no son tan claros, incluso si parecen ser así. Tenga en cuenta que la computadora no conoce estos conceptos y no se comporta de acuerdo con ella. La computadora no sabe acerca de los tipos. Por lo tanto, no hace una distinción de punteros y valores. Voy a tratar de explicar por e ejemplo:

void func1(int x) 
{ 
    x = 5; 
} 

void func2(int *x) 
{ 
    int a; 
    x = &a; 
} 

El funcionamiento es el mismo para la máquina en ambas funciones: Se pone el argumento y lo cambia. Tenga en cuenta que, en la segunda función no modifica * x, modifica x.

Ahora bien, si nos llaman a estas funciones,

int y = 10; 

func1(y); //value of y does not change 

func2(&y); //value of &y does not change, but the value of the address which y points may change. 

Yo prefiero decir que, básicamente , cada llamada a la función es "llamada por valor". Pero en el caso de un tipo de puntero, tenemos una forma de cambiar el contenido de otra dirección en la memoria.

Si hubiéramos escrito func2 como

void func2(int *x) 
{ 
    *x = 5; 
} 

Entonces, esto sería un caso real de "llamadas por referencia".

Cuestiones relacionadas