Foro de elhacker.net

Programación => Programación General => Mensaje iniciado por: xaps en 13 Noviembre 2013, 01:52 am



Título: POO - ¿Diferencia entre usar una constructora-copiadora a Objeto = Objeto?
Publicado por: xaps en 13 Noviembre 2013, 01:52 am
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.


Título: Re: POO - ¿Diferencia entre usar una constructora-copiadora a Objeto = Objeto?
Publicado por: 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.


Título: Re: POO - ¿Diferencia entre usar una constructora-copiadora a Objeto = Objeto?
Publicado por: xaps en 13 Noviembre 2013, 14:47 pm
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.


Título: Re: POO - ¿Diferencia entre usar una constructora-copiadora a Objeto = Objeto?
Publicado por: El Benjo en 13 Noviembre 2013, 20:44 pm
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:

Código
  1.  char A[22] = "Cadena";
  2.  char B[22];
  3.  B = A;
  4.  

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?


Título: Re: POO - ¿Diferencia entre usar una constructora-copiadora a Objeto = Objeto?
Publicado por: xaps en 14 Noviembre 2013, 14:15 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 (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).

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!


Título: Re: POO - ¿Diferencia entre usar una constructora-copiadora a Objeto = Objeto?
Publicado por: El Benjo en 15 Noviembre 2013, 05:37 am
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 (http://msdn.microsoft.com/es-es/library/yyaad03b(v=vs.90).aspx)


Título: Re: POO - ¿Diferencia entre usar una constructora-copiadora a Objeto = Objeto?
Publicado por: xaps en 15 Noviembre 2013, 14:24 pm
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,

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.


Título: Re: POO - ¿Diferencia entre usar una constructora-copiadora a Objeto = Objeto?
Publicado por: Mitsu 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 (http://elbauldelprogramador.com/lenguaje-c/clases-y-objetos-pasar-un-objeto-una/).


Título: Re: POO - ¿Diferencia entre usar una constructora-copiadora a Objeto = Objeto?
Publicado por: xaps en 15 Noviembre 2013, 22:54 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 (http://elbauldelprogramador.com/lenguaje-c/clases-y-objetos-pasar-un-objeto-una/).

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 (http://c.conclase.net/curso/index.php?cap=029), en el apartado "Asignación de objetos", donde dice:

Citar
La 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?


Título: Re: POO - ¿Diferencia entre usar una constructora-copiadora a Objeto = Objeto?
Publicado por: El Benjo en 16 Noviembre 2013, 06:13 am
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.


Título: Re: POO - ¿Diferencia entre usar una constructora-copiadora a Objeto = Objeto?
Publicado por: xaps en 16 Noviembre 2013, 18:47 pm
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.
Me alegro de que tu también hayas sacado algo de esto.

Por cierto, acabo de enteder el motivo de tu pregunta:
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?

Lo decias porque, al pasar un objeto por valor, hay que hacer una copia del objeto en questión y si el lenguaje de programación no permitia hacer una copia de un objeto mediante asignación, tampoco deberia permitirlo al pasarlo a una función por valor, ¿cierto?
Te comentaré algo más sobre C++ con lo que no había caido antes: Todos los tipos de datos en C++ son objetos, incluso los int. Esto podría explicar porqué se puede hacer la copia de un objeto mediante la asginación.


Título: Re: POO - ¿Diferencia entre usar una constructora-copiadora a Objeto = Objeto?
Publicado por: El Benjo en 16 Noviembre 2013, 20:15 pm
Te comentaré algo más sobre C++ con lo que no había caido antes: Todos los tipos de datos en C++ son objetos, incluso los int. Esto podría explicar porqué se puede hacer la copia de un objeto mediante la asginación.

Sí, a eso me refería precisamente con esa pregunta. :)

Pues sí, así es, a diferencia de C en lenguajes orientados a objetos los tipos fundamentales también son objetos, esto lo puedes apreciar mejor cuando escribes código de C# por ejemplo, cuando escribes el nombre de una variable de tipo integer seguida de un punto puedes ver los métodos de los que dispone dicho objeto.


Título: Re: POO - ¿Diferencia entre usar una constructora-copiadora a Objeto = Objeto?
Publicado por: xaps en 16 Noviembre 2013, 21:41 pm
Pues sí, así es, a diferencia de C en lenguajes orientados a objetos los tipos fundamentales también son objetos, esto lo puedes apreciar mejor cuando escribes código de C# por ejemplo, cuando escribes el nombre de una variable de tipo integer seguida de un punto puedes ver los métodos de los que dispone dicho objeto.

No me había fijado nunca en eso. Creía que era una característica de C++, pero por lo que dices es algo que tienen la mayoría de los lenguajes de programación con POO.

Muchas gracias a los dos por vuestra ayuda!

Saludos