Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 08-11-2011
TecnoBestia TecnoBestia is offline
Miembro
 
Registrado: jun 2010
Posts: 35
Poder: 0
TecnoBestia Va por buen camino
Como puedo asignar una copia de una instancia sin que sea una referencia.

Hola amigos, una vez más requiero de su gran ayuda.

Tengo una clase definida de esta manera:

Código:
Individuo=class(TObject)
  private
  protected
  public
    VClasificacion:VectorIR;
    VCoordenadas:VectorIR;
    Inercia:Double;
    VDistancias:VectorIR;
    TieneClasesVacias:Boolean;
    procedure CargarClasificacionYDistancias();
    procedure GenerarVecino(CantiParticion:Integer);
    procedure CGRealesParaClasificacion();
    function RecalcularInercia:Double;
  published
    //destructor Destroy; override;
end;
Si tengo dos variables Var1 y Var 2 de tipo Individuo, de manera que dependiendo de una condición, no importa cual sea, se debe guardar el contenido de Var1 en Var2 para luego cambiar Var1 o bien destruirlo para luego reutilizarlo. La situación es la siguiente, si ejecuto el siguiente código:

Código:
Var2:=Var1;
Var1.Destroy;
Esto me destruye también a Var2, me suena que lo anterior lo que hace es una asignación de punteros y cuando cambio Var1 luego de guardarlo en Var2, se me cambia lo contenido en Var1.

Mi pregunta es: ¿existe una forma de realizar la asignación de modo que se me guarde una copia y no una referencia al mismo espacio de memoria?

Con el fin de modificar luego una de las variables manteniendose la otra intacta.

Gracias de antemano por su valiosa ayuda.
Responder Con Cita
  #2  
Antiguo 08-11-2011
Avatar de escafandra
[escafandra] escafandra is offline
Miembro Premium
 
Registrado: nov 2007
Posts: 2.197
Poder: 20
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Escribe un procedimiento Assign que asigne todas las propiedades de tu clase.

TPersistent tiene ese método virtual, así que puedes derivar de TPersistenty completar tu Assign con las nuevas propiedades de tu clase.

Por supuesto puedes realizar tu método de asignación desde cero.

Cuando se realizan asignaciones de este tipo se debe tener cuidado al asignar punteros y en este sentido todos los objetos VCL lo son, así que tendrás que asignar contenidos. Por eso lo mejor es usar el Assign de las clases VCL y completar la asignación de lo propio de nuestra clase.

Saludos.
Responder Con Cita
  #3  
Antiguo 08-11-2011
TecnoBestia TecnoBestia is offline
Miembro
 
Registrado: jun 2010
Posts: 35
Poder: 0
TecnoBestia Va por buen camino
Muchas gracias. Cambie TObject por TPersistent y coloqué un nuevo procedimiento
Código:
  procedure Individuo.Assign(IndiEnviado:Individuo);
  begin
    VCoordenadas:= IndiEnviado.VCoordenadas;
    VClasificacion:=IndiEnviado.VClasificacion;
    VDistancias:=IndiEnviado.VDistancias;
    Inercia:=IndiEnviado.Inercia;
    TieneClasesVacias:=IndiEnviado.TieneClasesVacias;
  end;
y todo parece funcionar bien.

Gracias por su aporte y su valioso tiempo.
Responder Con Cita
  #4  
Antiguo 08-11-2011
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola TecnoBestia.

Me alegra que hayas solucionado el problema, pero creo que el amigo escafandra se refería a algo parecido a esto:
Código Delphi [-]
...
type
  TIndividuo = class(TPersistent)
    procedure Assign(aCustomer: TPersistent); override;
  private
    FNombre: string;
    FEdad: Integer;
    ...
  public
    ...
    property Nombre: string read FNombre write FNombre;
    property Edad  : integer read FEdad write FEdad;
   ...
  end;

procedure TIndividuo.Assign(aCustomer: TPersistent);
begin
  if aCustomer is TIndividuo then
  begin
    FNombre := TIndividuo(aCustomer).FNombre;
    FEdad   := TIndividuo(aCustomer).FEdad;
    ...
  end
  else
    inherited Assign (aCustomer);
end;
...
end.

//--------------------------------------------------------------
...
procedure TForm1.btnAssign(Sender: TObject);
var
  Individuo1, Individuo2: TIndividuo;
begin
  Individuo1 := TIndividuo.Create;
  Individuo1.Nombre := 'PEPE';
  Individuo1.Edad := 15;
  Individuo2 := TIndividuo.Create;
  Individuo2.Assign(Individuo1);
  Individuo1.Free;
  ShowMessage(Format('%s %d',[Individuo2.Nombre, Individuo2.Edad]));
  ...
end;

Un saludo.
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #5  
Antiguo 08-11-2011
Avatar de escafandra
[escafandra] escafandra is offline
Miembro Premium
 
Registrado: nov 2007
Posts: 2.197
Poder: 20
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Exacto, se trata de sobreescribir el método Assign para añadir en él las asignaciones de las propiedades propias de nuestra nueva clase, tal como muestra ecfisa en su código.

TecnoBestia, se trata de sobrecargar la función virtual para terminar llamando a la heredada, en otro caso te pierdes las propiedades de la clase madre.

Saludos.
Responder Con Cita
  #6  
Antiguo 08-11-2011
Avatar de Delphius
[Delphius] Delphius is offline
Miembro Premium
 
Registrado: jul 2004
Ubicación: Salta, Argentina
Posts: 5.582
Poder: 25
Delphius Va camino a la fama
¿Y Vale la pena heredar desde TComponent sólo por un método? Antes a cambios en la estructura jerárquicas de nuestras clases es mejor pensarlo dos veces.

¿Te aporta alguna otra ventaja que sea de la clase TComponent? ¿necesitarás hacer streaming para recuperar datos?

¿En que te afecta, o que tan complicado es directamente añadirle un método CopiarA() que haga un trabajo similar? Digo... siendo honestos es lo mismo que harías con el Assing:

Código Delphi [-]
ObjDestino.Propiedad := ObjFuente.Propiedad;

Con todo repeto, me parece un desperdicio heredar de TComponent si en verdad la clase no se va a comportar como un componente.

Saludos,
__________________
Delphius
[Guia de estilo][Buscar]
Responder Con Cita
  #7  
Antiguo 08-11-2011
Avatar de Al González
[Al González] Al González is offline
In .pas since 1991
 
Registrado: may 2003
Posts: 5.604
Poder: 29
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
Muy puntual lo dicho por ecfisa y escafandra.

Solamente una observación:
Cita:
Empezado por escafandra Ver Mensaje
[...] se trata de sobrecargar la función virtual para terminar llamando a la heredada [...]
Tratándose de la palabra reservada Override, el término es redefinir (en el ejemplo se redefine un método virtual), mientras que el término sobrecarga tiene que ver con el uso de Overload, lo cual es otro concepto. Seguro que escafandra así lo entiende también y fue simplemente un despiste.

Saludos.

Al González.
Responder Con Cita
  #8  
Antiguo 08-11-2011
[maeyanes] maeyanes is offline
Capo de los Capos
 
Registrado: may 2003
Ubicación: Campeche, México
Posts: 2.732
Poder: 24
maeyanes Va por buen camino
Hola...

Delphius, según creo recordar, TComponent desciende de TPersistent y no al revés. A lo que voy es que heredar una clase de TPersistent no hace que esta se comporte como un componente. TPersistent solo define métodos para serializar un objeto.


Saludos...
__________________
Lee la Guía de Estilo antes que cualquier cosa. - Twitter
Responder Con Cita
  #9  
Antiguo 08-11-2011
TecnoBestia TecnoBestia is offline
Miembro
 
Registrado: jun 2010
Posts: 35
Poder: 0
TecnoBestia Va por buen camino
Más sobre mi problema

Mi clase es muy simple y es para la aplicación de un algoritmo denominado Simulating Annealing para hacer clasificación de datos, mi clase es un Individuo que que contendrá únicamente lo que se muestra en el código siguiente:
Código PHP:
Individuo=class(TObject)
  private
  protected
  public
    
VClasificacion:VectorIR;
    
VCoordenadas:VectorIR;
    
Inercia:Double;
    
VDistancias:VectorIR;
    
TieneClasesVacias:Boolean;
    
procedure CargarClasificacionYDistancias();
    
procedure GenerarVecino(CantiParticion:Integer);
    
procedure CGRealesParaClasificacion();
    function 
RecalcularInercia:Double;
  
published
    
//destructor Destroy; override;
end
Si creo la clase derivada de TObject y genero el procedimiento GenerarCopia tal como se muestra en el código siguiente


Código PHP:
  procedure Individuo.GenerarCopia(IndiEnviado:Individuo);
  
begin
    VCoordenadas
:= IndiEnviado.VCoordenadas;
    
VClasificacion:=IndiEnviado.VClasificacion;
    
VDistancias:=IndiEnviado.VDistancias;
    
Inercia:=IndiEnviado.Inercia;
    
TieneClasesVacias:=IndiEnviado.TieneClasesVacias;
  
end
Y uso éste para poder realizar la copia y no la asignación del puntero, ¿qué problema tendría? ¿qué estoy perdiento al hacerlo así, ya que en este momento me está funcionando? Pero claro que si es mejor hacerlo de la manera que ustedes indican lo haré sin problema.
Responder Con Cita
  #10  
Antiguo 08-11-2011
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Cita:
Empezado por maeyanes Ver Mensaje
Delphius, según creo recordar, TComponent desciende de TPersistent y no al revés. A lo que voy es que heredar una clase de TPersistent no hace que esta se comporte como un componente. TPersistent solo define métodos para serializar un objeto.
Así es. Aún así, aplica lo que comenta Delphius. ¿Vale la pena derivar de TPersistent?

// Saludos
Responder Con Cita
  #11  
Antiguo 08-11-2011
Avatar de Delphius
[Delphius] Delphius is offline
Miembro Premium
 
Registrado: jul 2004
Ubicación: Salta, Argentina
Posts: 5.582
Poder: 25
Delphius Va camino a la fama
Cita:
Empezado por maeyanes Ver Mensaje
Hola...

Delphius, según creo recordar, TComponent desciende de TPersistent y no al revés. A lo que voy es que heredar una clase de TPersistent no hace que esta se comporte como un componente. TPersistent solo define métodos para serializar un objeto.


Saludos...
¡Tienes razón! Siempre me confundo a estas dos clases. Tengo que estudiar más y mejor

Pero como dijo román, el planteo sigue siendo igual de válido. ¿Vale la pena heredar la clase sólo por un método? Yo no creo.

Saludos,
__________________
Delphius
[Guia de estilo][Buscar]
Responder Con Cita
  #12  
Antiguo 08-11-2011
TecnoBestia TecnoBestia is offline
Miembro
 
Registrado: jun 2010
Posts: 35
Poder: 0
TecnoBestia Va por buen camino
Hola, ¿De quien me recomiendan heredar?
¿Puedo heredar de TOject y crear un procedimiento Copiar? algó así como
Código PHP:
  procedure Individuo.CopiarInstancia(IndiEnviado:Individuo);
  
begin
    VCoordenadas
:= IndiEnviado.VCoordenadas;
    
VClasificacion:=IndiEnviado.VClasificacion;
    
VDistancias:=IndiEnviado.VDistancias;
    
Inercia:=IndiEnviado.Inercia;
    
TieneClasesVacias:=IndiEnviado.TieneClasesVacias;
  
end
¿pierdo algo al hacerlo así?

Gracias por sus acertadas respuestas .
Responder Con Cita
  #13  
Antiguo 08-11-2011
[maeyanes] maeyanes is offline
Capo de los Capos
 
Registrado: may 2003
Ubicación: Campeche, México
Posts: 2.732
Poder: 24
maeyanes Va por buen camino
Hola...

Para tu caso en particular, no veo por que no hacerlo así, ya que es una clase simple y no necesitas sobrecargarla con métodos que ni vas a usar.


Saludos...
__________________
Lee la Guía de Estilo antes que cualquier cosa. - Twitter
Responder Con Cita
  #14  
Antiguo 08-11-2011
TecnoBestia TecnoBestia is offline
Miembro
 
Registrado: jun 2010
Posts: 35
Poder: 0
TecnoBestia Va por buen camino
Gracias, lo haré así.
Responder Con Cita
  #15  
Antiguo 08-11-2011
Avatar de escafandra
[escafandra] escafandra is offline
Miembro Premium
 
Registrado: nov 2007
Posts: 2.197
Poder: 20
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Y volviendo a la idea de Delphius si la clase es tan simple, ¿porqué definirla como derivada de otra? ¿Que se quiere heredar?


Saludos.
Responder Con Cita
  #16  
Antiguo 08-11-2011
Avatar de escafandra
[escafandra] escafandra is offline
Miembro Premium
 
Registrado: nov 2007
Posts: 2.197
Poder: 20
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Cita:
Empezado por Al González Ver Mensaje
Tratándose de la palabra reservada Override, el término es redefinir (en el ejemplo se redefine un método virtual), mientras que el término sobrecarga tiene que ver con el uso de Overload, lo cual es otro concepto. Seguro que escafandra así lo entiende también y fue simplemente un despiste.
Tienes toda la razón en tu observación Al González, así lo entiendo yo también.

Saludos.
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Como Puedo Asignar un TObjetList a un CxBdlookupCombobox Sin Recorrer La Lista joelphi Conexión con bases de datos 1 14-02-2009 02:44:29
¿Cómo puedo saber el tamaño que debo asignar al buffer? MON___ API de Windows 5 02-02-2008 22:08:02
Como puedo librarme de la referencia circular? Lionheart OOP 2 13-12-2005 13:58:33
Como puedo asignar un ip a un equipo yayita Internet 3 12-03-2004 22:09:52
Como puedo saber si un una variable instancia se le a realiso un create orfeo OOP 1 05-05-2003 08:42:38


La franja horaria es GMT +2. Ahora son las 05:12:43.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi