Pase por referencia / valor en C ++

Me gustaría aclarar las diferencias entre por valor y por referencia.

Dibujé una imagen

enter image description here

Entonces, para pasar por valor,

se crea una copia de un objeto idéntico con una referencia diferente, y a la variable local se le asigna la nueva referencia, para apuntar a la nueva copia

Cómo entender las palabras: “Si la función modifica ese valor, las modificaciones también aparecen dentro del scope de la función de llamada tanto para pasar por valor como por referencia”

¡Gracias!

Creo que se genera mucha confusión al no comunicar lo que se entiende por aprobado por referencia . Cuando algunas personas dicen pasar por referencia , generalmente no se refieren al argumento en sí, sino al objeto al que se hace referencia . Algunos otros dicen que pasar por referencia significa que el objeto no puede ser cambiado en el destinatario. Ejemplo:

struct Object { int i; }; void sample(Object* o) { // 1 o->i++; } void sample(Object const& o) { // 2 // nothing useful here :) } void sample(Object & o) { // 3 o.i++; } void sample1(Object o) { // 4 o.i++; } int main() { Object obj = { 10 }; Object const obj_c = { 10 }; sample(&obj); // calls 1 sample(obj) // calls 3 sample(obj_c); // calls 2 sample1(obj); // calls 4 } 

Algunas personas afirmarían que 1 y 3 son pasadas por referencia, mientras que 2 pasarían por valor. Otro grupo de personas dice que todo menos el último es aprobado por referencia, porque el objeto en sí no se copia.

Me gustaría hacer una definición de eso aquí, lo que afirmo que es aprobado por referencia . Aquí puede encontrar una descripción general: Diferencia entre pasar por referencia y pasar por valor . El primero y el último pasan por valor y los dos medios pasan por referencia:

  sample(&obj); // yields a `Object*`. Passes a *pointer* to the object by value. // The caller can change the pointer (the parameter), but that // won't change the temporary pointer created on the call side (the argument). sample(obj) // passes the object by *reference*. It denotes the object itself. The callee // has got a reference parameter. sample(obj_c); // also passes *by reference*. the reference parameter references the // same object like the argument expression. sample1(obj); // pass by value. The parameter object denotes a different object than the // one passed in. 

Voto la siguiente definición:

Un argumento (1.3.1) se pasa por referencia si y solo si el parámetro correspondiente de la función que se llama tiene un tipo de referencia y el parámetro de referencia se une directamente a la expresión del argumento (8.5.3 / 4). En todos los demás casos, tenemos que ver con pasar por valor.

Eso significa que lo siguiente es pasar por valor:

 void f1(Object const& o); f1(Object()); // 1 void f2(int const& i); f2(42); // 2 void f3(Object o); f3(Object()); // 3 Object o1; f3(o1); // 4 void f4(Object *o); Object o1; f4(&o1); // 5 

1 es pasar por valor, porque no está directamente vinculado. La implementación puede copiar el temporal y luego vincular ese temporal a la referencia. 2 es pasar por valor, porque la implementación inicializa un carácter temporal del literal y luego se une a la referencia. 3 es pasar por valor, porque el parámetro no tiene tipo de referencia. 4 es pasar por valor por la misma razón. 5 es pasar por valor porque el parámetro no tiene tipo de referencia. Los siguientes casos se pasan por referencia (según las reglas de 8.5.3 / 4 y otros):

 void f1(Object *& op); Object a; Object *op1 = &a; f1(op1); // 1 void f2(Object const& op); Object b; f2(b); // 2 struct A { }; struct B { operator A&() { static A a; return a; } }; void f3(A &); B b; f3(b); // passes the static a by reference 

Al pasar por valor:

 void func(Object o); 

y luego llamar

 func(a); 

construirá un Object en la stack, y dentro de la implementación de func se hará referencia a o . Esto aún puede ser una copia superficial (las partes internas de a y o podrían apuntar a los mismos datos), por lo que a podría cambiarse. Sin embargo, si o es una copia profunda de a , entonces a no cambiará.

Al pasar por referencia:

 void func2(Object& o); 

y luego llamar

 func2(a); 

solo le dará una nueva forma de referencia a . ” a ” y ” o ” son dos nombres para el mismo objeto. Cambiar o dentro de func2 hará que esos cambios sean visibles para la persona que llama, que conoce el objeto con el nombre ” a “.

¡Muchas gracias a todos por todas estas aportaciones!

Cité esa oración en una nota de conferencia en línea: http://www.cs.cornell.edu/courses/cs213/2002fa/lectures/Lecture02/Lecture02.pdf

la primera página la 6ta diapositiva

“Pase por VALOR El valor de una variable se pasa a lo largo de la función. Si la función modifica ese valor, las modificaciones permanecen dentro del scope de esa función.

Pase por REFERENCIA Una referencia a la variable se pasa a lo largo de la función. Si la función modifica ese valor, las modificaciones también aparecen dentro del scope de la función de llamada.

Muchas gracias de nuevo!

No estoy seguro si entiendo tu pregunta correctamente. No está un poco claro Sin embargo, lo que podría confundirte es lo siguiente:

  1. Al pasar por referencia, se pasa una referencia al mismo objeto a la función a la que se llama. Cualquier cambio en el objeto se reflejará en el objeto original y, por lo tanto, la persona que llama lo verá.

  2. Al pasar por valor, se llamará al constructor de copia. El constructor de copia predeterminado solo hará una copia superficial, por lo tanto, si la función llamada modifica un entero en el objeto, la función llamante no lo verá, pero si la función cambia una estructura de datos apuntada por un puntero dentro del objeto , esto será visto por la persona que llama debido a la copia superficial.

Pude haber entendido mal tu pregunta, pero pensé que podría darle una puñalada de todos modos.

Cuando lo analizo, esas palabras son incorrectas. Debería decir “Si la función modifica ese valor, las modificaciones también aparecen dentro del scope de la función de llamada cuando se pasa por referencia, pero no cuando se pasa por valor”.

Mi comprensión de las palabras “Si la función modifica ese valor, las modificaciones también aparecen dentro del scope de la función de llamada para pasar por valor y por referencia” es que son un error .

Las modificaciones realizadas en una función llamada no están dentro del scope de la función de llamada cuando se pasa por valor.

O bien, ha escrito mal las palabras citadas o se las ha extraído de cualquier contexto que haya hecho lo que parece estar mal, ¿verdad?

¿Podría asegurarse de haber citado correctamente su fuente y, si no hay errores, dar más texto en torno a esa statement en el material de origen?