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 16-12-2013
TecnoBestia TecnoBestia is offline
Miembro
 
Registrado: jun 2010
Posts: 35
Poder: 0
TecnoBestia Va por buen camino
Cómo modificar una instancia dentro de un procedimiento asociado a esta.

Hola foreros.

Tengo una duda que me trabado y no he podido encontrar nada al respecto. Supongo que para muchos de ustedes es algo muy sencillo. Por lo que les pido su ayuda.

Tengo una instancia que perteneces a una clase creada por mí denominada TParticula. Luego tengo un vector llamado VEnjambre lleno de instancias del tipo TParticula.

Para la clase TParticula se le programó un procedimiento que dependiendo del resultado modifica la instancia, sin embargo este cambio no se hace.

Veamoslo en Código:
Código:
       for i:=0 to Tamano_Del_Enjambre-1 do begin
         VEnjambre[i].AplicarBusquedaTabu;
         if VEnjambre[IndiceDeLaMejorParticulaDeLaHistoria].ValorInerciaEnMejorPosicion<VEnjambre[i].ValorInerciaEnMejorPosicion then begin
           IndiceDeLaMejorParticulaDeLaHistoria:=i;
         end;
       end;
Luego en el segundo paso del procedimiento anterior corresponde al sigueinte procedimiento.

Código:
procedure TParticula.AplicarBusquedaTabu();
var
  i,IteraBT:Integer;
begin
  
  IteraBT:=0;
  SetLength(Self.ListaTabu,2,TamaMaxListaTabu);
  while IteraBT<MaxIteraSinMejorasBT do
  begin
    IteraBT:=IteraBT+1;
    Self.BTCrearVecino(BTTamaVecindario);
    if Self.SeGeneroElVecino then begin
      Self:=VecinoParticula.Clon;                    //Aquí 1
      FreeAndNil(VecinoParticula);
      if Self.ValorDeLaInerciaActual<Self.ValorInerciaEnMejorPosicion then begin
        IteraBT:=0;
        Self.ValorInerciaEnMejorPosicion:=Self.ValorDeLaInerciaActual;            //Aquí 2
        Self.VCoordenadasMejorPosicion:=Copy(Self.VCoordenadasActual);      //Aquí 3
      end;
      

    end;
  end;
end;
Tanto en Aquí 1, 2 y 3 se hacen cambios a la instancia, sin embargo al finalizar dicho procedimiento no los cambios no se ven.

Es decir, valor que sale de procedimiento AplicarBusquedaTabu es el mismo que entró y los cambios que se hacen dentro del procedimiento no se aplican fuera.

Es como si el self fuera una copia de la instancia y no una referencia a la instancia dada.

Agradezco cualquier ayuda.

Saludos...
Responder Con Cita
  #2  
Antiguo 17-12-2013
Avatar de Ñuño Martínez
Ñuño Martínez Ñuño Martínez is offline
Moderador
 
Registrado: jul 2006
Ubicación: Ciudad Catedral, Españistán
Posts: 6.000
Poder: 25
Ñuño Martínez Tiene un aura espectacularÑuño Martínez Tiene un aura espectacular
Cita:
Empezado por TecnoBestia Ver Mensaje
Es como si el self fuera una copia de la instancia y no una referencia a la instancia dada.
No, SELF es una referencia al objeto que está asociado a la instancia en ejecución. No puede cambiarse.

Creo que deber revisar tus apuntes sobre Programación Orientada a Objetos.
__________________
Proyectos actuales --> Allegro 5 Pascal ¡y Delphi!|MinGRo Game Engine
Responder Con Cita
  #3  
Antiguo 17-12-2013
TecnoBestia TecnoBestia is offline
Miembro
 
Registrado: jun 2010
Posts: 35
Poder: 0
TecnoBestia Va por buen camino
Hola, entiendo que self es una referencia a un objeto, pero no entiendo por que no puede cambiarse, en otros lugares he usado la instrucción

Código:
  VecinoParticula:=VecinoAux9.Clon;
y también
Código:
VecinoAux9:=Self.Clon;
y no he tenido ningún problema siendo VecinoParticula y VecinoAux9 instancias de la misma clases, la función Clon lo que hace es crear una compia del objeto para que no sea una referencia.

El procedimiento correspondiente es:

Código:
function clsParticula.Clon():clsParticula;
var
i:Integer;                             {Esta función realiza un clon independiete, elimina el uso de punteros en las instancias}
begin
  Result:=clsParticula.Create;
  Result.VClasificacion:=Copy(Self.VClasificacion);
  Result.VCoordenadasActual:=Copy(Self.VCoordenadasActual);
  Result.VCoordenasPosicionAnterior:=Copy(Self.VCoordenasPosicionAnterior);
  Result.VCoordenadasMejorPosicion:=Copy(Self.VCoordenadasMejorPosicion);
  Result.VDistancias:=Copy(Self.VDistancias);
  Result.ValorDeLaInerciaActual:=Self.ValorDeLaInerciaActual;
  Result.ValorInerciaEnMejorPosicion:=Self.ValorInerciaEnMejorPosicion;
  Result.VCardinalidades:=Copy(Self.VCardinalidades);
  Result.VVelocidad:=Copy(Self.VVelocidad);
  //Tabu
  Result.OperaRealizadaVecino:=Self.OperaRealizadaVecino;
  Result.PosicionModificadaParaVecino:=Self.PosicionModificadaParaVecino;
  Result.PosicionAActualizarEnLT:=Self.PosicionAActualizarEnLT;

  SetLength(Result.ListaTabu,2,TamaMaxListaTabu);

  Result.ListaTabu[0]:=Copy(Self.ListaTabu[0]);
  Result.ListaTabu[1]:=Copy(Self.ListaTabu[1]);

  Result.TamaActualLT:=Self.TamaActualLT;
  Result.SeGeneroElVecino:=Self.SeGeneroElVecino;
end;
Donde result posee una copia del objeto independiente de la instancia general. Mi duda es ¿por qué no puedo cambiar el self pero si otras referencias de los objetos?, y más aún ¿cómo puedo solucionar el problema?

Saludos...
Responder Con Cita
  #4  
Antiguo 18-12-2013
Avatar de Ñuño Martínez
Ñuño Martínez Ñuño Martínez is offline
Moderador
 
Registrado: jul 2006
Ubicación: Ciudad Catedral, Españistán
Posts: 6.000
Poder: 25
Ñuño Martínez Tiene un aura espectacularÑuño Martínez Tiene un aura espectacular
Porque SELF no es una variable, sino una constante. Siempre es la referencia (puntero) al objeto del método que se está ejecutando en ese momento.

Cuando defines un método de una clase, como por ejemplo:
Código Delphi [-]
  TMiClase = CLASS
  PUBLIC
    PROCEDURE Metodo (aVariable: STRING);
  END;

en realidad el compilador lo interpreta como si fuera así:
Código Delphi [-]
  TMiClase = CLASS
  PUBLIC
    PROCEDURE Metodo (CONST Self: TMiOBjeto; aVariable: STRING);
  END;

Y cuando llamas al método:
Código Delphi [-]
  MiObjeto.Metodo ('Hola');

El compilador lo interpreta como si fuera así:
Código Delphi [-]
  TMiClase.Metodo (MiObjeto, 'Hola');

El caso de RESULT es diferente, ya que sí es una variable cuya posición de memoria se corresponde con la posición de pila donde el llamante tomará el valor devuelto por la función. En cierto modo, una definición como:
Código Delphi [-]
  FUNCTION UnaFuncion (aValor: INTEGER): INTEGER;
Se interpreta como si fuera:
Código Delphi [-]
  PROCEDURE UnaFuncion ( OUT RESULT: INTEGER; aValor: INTEGER);
y si fuera método de una clase...
Código Delphi [-]
  PROCEDURE UnaFuncion (CONST SELF: TMiClase; OUT RESULT: INTEGER; aValor: INTEGER);
__________________
Proyectos actuales --> Allegro 5 Pascal ¡y Delphi!|MinGRo Game Engine

Última edición por Ñuño Martínez fecha: 18-12-2013 a las 14:20:18.
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 modificar una variable externa en un procedimiento?? jasmad Lazarus, FreePascal, Kylix, etc. 6 01-12-2011 23:40:38
condicionar un procedimiento dentro de otro procedimiento yossi Varios 7 17-05-2010 10:47:14
Abrir fichero asociado si la aplicacion ya esta activa. Geta Varios 4 13-03-2009 01:43:51
Como hacer un commit dentro de un procedimiento almacenado altp Firebird e Interbase 6 03-11-2005 18:21:32
Como modificar valores desde un dbgrid q esta asociado a un QUERY? fmonte SQL 12 26-08-2004 22:25:22


La franja horaria es GMT +2. Ahora son las 22:17:01.


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