POO - ¿Diferencia entre usar una constructora-copiadora a Objeto = Objeto?

Iniciado por xaps, 13 Noviembre 2013, 01:52 AM

0 Miembros y 1 Visitante están viendo este tema.

xaps

Mientras desarrollaba una pequeña clase Matriz, me ha surgido una duda: ¿Que diferencia hay entre usar una constructora copiadora o igualar dos objetos (ej: mat1 = mat2, siendo mat1 y mat2 objetos de la clase Matriz)?
En este caso, la constructora-copiadora hacía uso de los típicos dos bucles for para recorrer toda la matriz y ir copiandola al parámetro implícito (formato constructora: Matriz(Matriz &mat); ), pero me ha surgido la duda de si era más eficiente igualar dos objetos de tipo matriz y olvidarme de la constructora-copiadora. Por eso, me gustaría saber que ocurre realmente cuando igualas dos objetos del mismo tipo.

Saludos y gracias.
"The programmers of tomorrow are the wizards of the future" - Gave Newel

El Benjo

Que cuando haces Objeto = Objeto2 estás diciendo que la dirección de Objeto es la misma dirección de memoria que Objeto2, es decir, estás diciendo que Objeto y Objeto2 son dos referncias distintas a la misma posición de memoria. Así que si modificas cualquier propiedad de Objeto al leer la misma propiedad en Objeto2 obtendrás el valor ya modificado.

Saludos.
www.es.neftis-ai.com

Sí hay un mejor lenguaje de programación y es ese con el que puedes desarrollar tus objetivos.

xaps

Cita de: El Benjo en 13 Noviembre 2013, 05:18 AM
Que cuando haces Objeto = Objeto2 estás diciendo que la dirección de Objeto es la misma dirección de memoria que Objeto2, es decir, estás diciendo que Objeto y Objeto2 son dos referncias distintas a la misma posición de memoria. Así que si modificas cualquier propiedad de Objeto al leer la misma propiedad en Objeto2 obtendrás el valor ya modificado.

Saludos.

¿Y ocurre siempre lo mismo en todos los lenguajes que permitan POO? Me había imaginado una respuesta del tipo: "Depende del lenguaje de programación o del compilador usado", ya que al ser una asignación alomejor distintos lenguajes y compiladores lo interpretaban distinto.
"The programmers of tomorrow are the wizards of the future" - Gave Newel

El Benjo

Estoy CASI seguro de que en todos los lenguajes orientaos a objetos es así. Sin embargo hay que recordar que incluso los lenguajes no orientados a objetos nos impiden hacer eso. ejemplo: En el lenguaje C para copiar el valor de una cadena de caracteres (que es un arreglo unidimensional) se disponen de funciones especiales para dicho propósito y no se puede hacer simplemente:


  char A[22] = "Cadena";
  char B[22];
  B = A;


En lenguajes de alto nivel se puede hacer esto porque el compilador crea rutinas que copian cada caracter de una cadena a la otra, sin embargo yo no sé de algún lenguaje de programación que permita hacer esto con otro tipo de objetos sin recurrir a una función especial.

Menciona el lenguaje en el que estás trabajando y veremos si podemos encontrar algo al respecto.

NOTA: Creo que esto puede aclarar todo. ¿Te has preguntado por qué los objetos se pasan a una función por referencia y no por valor?
www.es.neftis-ai.com

Sí hay un mejor lenguaje de programación y es ese con el que puedes desarrollar tus objetivos.

xaps

Cita de: El Benjo en 13 Noviembre 2013, 20:44 PM
NOTA: Creo que esto puede aclarar todo. ¿Te has preguntado por qué los objetos se pasan a una función por referencia y no por valor?

Se que cuando pasas un parámetro por referencia, lo que estás haciendo realmente es pasar su dirección de memoria y operar directamente con los datos ya creados antes, sin tener que crear una copia como ocurre cuando lo pasas por valor.

Dicho esto, ¿Un objeto siempre se debe pasar por referencia? Nunca me he fijado en ese detalle, pero pensándolo bien, si que es verdad que muy pocas veces he pasado un objeto por valor. Supongo que será por temas de memoria o similares, pero se puede hacer (almenos en C++) ya que buscando un error en una clase que estoy desarrollando  (http://foro.elhacker.net/programacion_cc/error_al_usar_const_en_funciones_de_una_clase-t402724.0.html) elimine los tags "const" y "&" del objeto que le pasaba a la función para solucionar el error temporalmente (Me harías un favor si le echases un ojo).

Cita de: El Benjo en 13 Noviembre 2013, 20:44 PM
Menciona el lenguaje en el que estás trabajando y veremos si podemos encontrar algo al respecto.

Estoy trabajando con C# y C++ por el momento.

Muchas gracias!
"The programmers of tomorrow are the wizards of the future" - Gave Newel

El Benjo

Ok, es cierto, en C++ sí es posible pasar un objeto por valor o por referencia, sin embargo en C# no es posible.

Creo que finalmente esto nos aclara todo de la siguiente manera:


  • En C++: Es posible crear una nueva matriz que sea una copia de otra sin recurrir a una rutina o función para ello sólo en el caso de que esa copia se utilice dentro de una función (es decir, llamando a la función con la matriz como argumento)
  • En C#: No es posible hacer una copia de los valores de una matriz sin una rutina especializada para ello (ejemlo: bucle 'for' que recorra todos los elementos)

Te dejo el siguiente enlace donde se describen las diferencias entre C++ y C#. Espero que te sirva.

http://msdn.microsoft.com/es-es/library/yyaad03b(v=vs.90).aspx
www.es.neftis-ai.com

Sí hay un mejor lenguaje de programación y es ese con el que puedes desarrollar tus objetivos.

xaps

Muchas gracias por la ayuda, pero ahora tengo otra duda. ¿Que relación hay entre poder pasar un objeto por referencia y/o valor a una función, y el hecho de poder copiar un objeto mediante Objeto = Objeto? Es decir,

Cita de: El Benjo en 13 Noviembre 2013, 20:44 PM
NOTA: Creo que esto puede aclarar todo. ¿Te has preguntado por qué los objetos se pasan a una función por referencia y no por valor?

cual es el motivo/relación de esta pregunta con el tema del post? Ya que según he visto, has llegado a las conclusiones del último mensaje gracias a la respuesta a esa pregunta.
"The programmers of tomorrow are the wizards of the future" - Gave Newel

Mitsu

Pasar un objeto por valor es lo que normalmente hacemos. En el caso de Java, los parámetros de tipos básicos se pasan por valor y los objetos por referencia. Esto significa que a todo valor que reciba una función, le hará una copia y trabajará con ella.

Cuando se dice que se pasa por referencia, lo que estamos haciendo es accediendo a la dirección de memoria del objeto pero mediante una copia también. Esta copia es la que permite el acceso a la dirección del objeto. De esta manera, si se modifica la copia del objeto, se modificará también el objeto original.

Más información: Pasar por valor y por referencia en una función.

xaps

Cita de: M1t$u en 15 Noviembre 2013, 15:13 PM
Pasar un objeto por valor es lo que normalmente hacemos. En el caso de Java, los parámetros de tipos básicos se pasan por valor y los objetos por referencia. Esto significa que a todo valor que reciba una función, le hará una copia y trabajará con ella.

Cuando se dice que se pasa por referencia, lo que estamos haciendo es accediendo a la dirección de memoria del objeto pero mediante una copia también. Esta copia es la que permite el acceso a la dirección del objeto. De esta manera, si se modifica la copia del objeto, se modificará también el objeto original.

Más información: Pasar por valor y por referencia en una función.

Yo tenia entendido que cuando pasabas por referencia no se hacía ninguna copia, y que precisamente por eso los objetos y estructuras de datos de tamaño considerable se enviaban por referencia, para evitar la copia y el consumo de memoria. Y es más, en el enlace que me has pasado no se habla de copias cuando pasas por referencia, si no que más bien parece que cuando trabajas con una variable referenciada es como si trabajases con un puntero, provocando que cualquier modificación se haga en la variable real y no la referenciada. ¿Estoy en lo cierto?

Pero mi duda ahora mismo es como ha relacionado "El Benjo" este concepto con el que explico en el post (Objeto = Objeto) para llegar a esa conclusión.

Muchas gracias por dedicar unos minutos a este post, de verdad. Uno aprende mucho con gente como vosotros.

EDITO:

He encontrado algo interesante en http://c.conclase.net/curso/index.php?cap=029, en el apartado "Asignación de objetos", donde dice:

CitarLa línea "par2 = par1;" copia los valores de los datos miembros de par1 en par2.
En realidad, igual que pasa con los constructores, el compilador crea un operador de asignación por defecto, que copia los valores de todos los datos miembro de un objeto al otro. Veremos más adelante que podemos redefinir ese operador para nuestras clases, si lo consideramos necesario.

Lo que nos está diciendo es que el compilador se las arregla para copiar todos los datos de un objeto al otro, ¿cierto? Entonces, que un método sea más rápido que el otro dependerá de la calidad de tu código y la del compilador, ¿me equivoco?
"The programmers of tomorrow are the wizards of the future" - Gave Newel

El Benjo

Pues sí, parece que es cierto y es precisamente lo que se comentaba que las reglas para lenguajes del tipo C# y JAVA manejan distinto las instrucciones "Obj1 = Obj2" de la forma en que lo haría C++.

Creo que todos los que nos involucramos en este tema hemos aprendido algo nuevo. De verdad yo no tenía idea de que en C++ se pudiera realizar la asignación en esa forma.
www.es.neftis-ai.com

Sí hay un mejor lenguaje de programación y es ese con el que puedes desarrollar tus objetivos.