Ver Mensaje Individual
  #16  
Antiguo 31-10-2012
Avatar de Al González
[Al González] Al González is offline
In .pas since 1991
 
Registrado: may 2003
Posts: 5.604
Reputación: 30
Al González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en bruto
Cita:
Empezado por ecfisa Ver Mensaje
Código Delphi [-]
...
function TMiClase.Clone: TMiClase;
begin
  Result:= TMiClase.Create;
  Move(Self,Result,SizeOf(Self));
end;
...
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...
Hola ecfisa . Seguramente recordarás que los dos primeros parámetros de Move no son punteros a los buffers origen y destino, sino los buffers en sí (parámetros sin tipo). Es decir, de esa forma está copiando el puntero Self sobre el puntero Result (igual que una sentencia "Result := Self") y "SizeOf(Self)" devuelve el tamaño de un puntero: 4 bytes (u 8 en ejecutables de 64 bits).

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:
  • Campos (directos o indirectos) que llevan conteo de referencias, como cadenas String, interfaces, arreglos dinámicos (lo mencionado por Román).
  • Sub-objetos internos que también deban ser clonados.
  • Campos THandle que guardan identificadores únicos provenientes de APIs (como es el caso de los controles de la VCL).
  • Campos puntero hacia estructuras particulares del objeto.

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.
Responder Con Cita