![]() |
¿Qué diferencia hay entre copiar y clonar objetos?
Hola,
Nunca uso estas características de la OOP en Delphi, ¿me podríais asesorar un poco? Muchas gracias. |
¿En delphi se pueden clonar objetos? Será en las nuevas versiones porque antes no era posible.
En todo caso, aunque no sé si responda a tu duda, has de saber que en delphi las variables de tipo objeto son, en realidad, apuntadores al objeto, de manera que, cuando copias uno a otro:
en realidad sólo estás copiando los apuntadores, de forma que ObjetoA y ObjetoB son dos apuntadores que apuntan al mismo objeto. Si haces un cambio en las propiedades de ObjetoA, dicho cambio se reflejará en ObjetoB. Una clonación de objetos -que, repito, no sabía que se puede hacer en delphi- es crear un objeto aparte pero exactamente igual al primero. En ese caso, los cambios a un objeto ya no se reflejarían en el otro. En el caso de delphi 7, que es el que conozco, no existe tal cosa como la clonación de objetos, aunque hay algo similar en los objetos de la clase TPersistent (y derivadas) con los métodos Assign y AssignTo, con los cuales se pretende hacer una copia de un objeto, aunque no es tanto como una clonacón y muchas veces tiene uno que implementar dichos métodos explícitamente. // Saludos |
A mi me gustaría ver noob, un pequeño ejemplo de copiar un objeto y clonar un objeto, para saber de qué estamos hablando.
|
Hola,
Lo he resuelto. roman, he visto una forma de clonar objetos en Delphi. Neftali, pongo un ejemplo de todo lo que he hecho. Por ejemplo, tengo un objeto 'myObject' que quiero mantener en el atributo 'FObject' de otro objeto, pero quiero que mantenga su valor original aunque el objeto 'myObject' cambie en un futuro. Para ello, no me queda otra que clonar el objeto. Pongo el código que he utilizado:
Luego, quiero que ese objeto clonado tenga los mismos valores que el objeto 'myObject', por ello, hago una copia:
El uso desde una clase externa a 'cMyClass' sería así:
Funciona como esperaba, espero que se entienda y le sirva a alguien. Saludos. |
Bueno, lo que estás haciendo es similar a lo que te comenté del AssignTo del objeto TPersitent. Realmente el método Clone sale sobrando:
// Saludos |
Hola noob.
También podrías hacer la creación y copia de los atributos en un paso:
Saludos. |
Cita:
Gracias por la explicación. |
Cita:
// Saludos |
Cita:
Saludos. :) |
A ver si este artículo de Zarko Gajic titulado "How to clone a Delphi form" aclara o ayuda algo.
|
Es interesante, y supongo que puede hacerse con cualquier objeto de la clase TPersistent. Para objetos en general, el problema no está tanto con las propiedades, como dije arriba, puesto que si se copia toda la imagen del objeto en memoria, tal como hace ecfisa, supongo que también se copiarán los campos privados y, en general, el estado del objeto desde el cual se leen las propiedades. Pero el problema son las referencias; subobjetos, cadenas, etc.
Este tema lo tiene dominado Al González, según entiendo. En este hilo menciona que algun vez resolvió ese problema y menciona cuáles son los puntos a tomar en cuenta. No es trabajo fácil. // Saludos |
Cita:
Y en ella pareciera que campos, propiedades y eventos son conservados mediante la llamada a Clone. Sin embargo no sé por qué, pienso que se me está escapando algo... Saludos. :) |
Pero, por ejemplo, si haces:
Es decir, c2.Cadena y c1.Cadena hacen referencia a la misma cadena. En un clonación, el objeto clonado debería ser inicialmente igual al original en todo aspecto pero cambios posteriores no deberían afectar al otro. Lo mismo sucedería si tu objeto tuviera otros objetos como propiedades. Por otra parte, un string lleva un conteo de referencia que, me parece, se alteraría con una asignación usando Move. Es decir, habría dos variables apuntando a la misma cadea pero con un conteo de referencia igual a 1. Haz la prueba:
Y ni qué decir de interfaces, que también llevan un conteo de referencias. // Saludos |
Hola roman.
Quedó aclarado lo que se me estaba escapando ;) Saludos. :) |
Por ahí vi que nuestro amigo Al estaba respondiendo a este hilo :) Con seguridad tiene algo interesante que decir ^\||/.
// Saludos |
Cita:
Ambas direcciones de memoria pueden ser "desreferidas" (¿está bien escrito, Ñuño? ;)) y usar el método InstanceSize en lugar de la función SizeOf, a fin de conseguir con Move la copia que se quiere. Pero, se atraviesan algunos problemas:
El primer punto se resuelve mediante las funciones _CopyRecord y _CopyObject (aunque ésta última parece estar incompleta y sólo llamar a _CopyRecord). Pero el resto de los puntos son quizá la razón de por qué la clonación de bajo nivel es un tema relegado a la alquimia. :) De ahí que hoy, cuando deseo realizar alguna clonación de objetos, me limito a crear un objeto de la misma clase al cual copio sólo las propiedades publicadas, disponibles mediante reflexión (RTTI), y evitando aquellas que pudieran causar algún conflicto. Saludos. |
Cita:
// Saludos |
Cita:
Esa referencia de 2004 me hizo recordar que tardé muchos años en salir de la adolescencia :o. Aunque ya desde entonces planteaba cosas raras :p. Cita:
Claro está que algo así debe tratarse con sumo cuidado, por las razones antes mencionadas. |
Hola Al.
Te estoy muy agradecido (al igual que a roman) por ampliar la explicación del motivo y documentarlo claramente paso a paso. ;) Un tema interesante y que nunca se me cruzó para abordarlo. (Y para que la idea no acumule polvo encima, me pondré a investigar y probar sobre ella) Saludos :) |
La franja horaria es GMT +2. Ahora son las 12:47:39. |
Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi