Ver Mensaje Individual
  #1  
Antiguo 20-12-2015
Avatar de AgustinOrtu
[AgustinOrtu] AgustinOrtu is offline
Miembro Premium
NULL
 
Registrado: ago 2013
Ubicación: Argentina
Posts: 1.858
Reputación: 17
AgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en bruto
Estudiando constructores y destructores

Segun la documentacion, en el constructor de un objeto todas las referencias a otros objetos son asignadas automaticamente a NIL

Es decir, teniendo esta clase

Código Delphi [-]
  TTestClass = class
  public
    Object: TObject;
  end;

procedure Test;
var
  LTest: TTestClass;
begin
  LTest := TTestClass.Create;
  LTest.Object ---> NIL

  LTest.Object.Free --> Llamada segura, Free va a chequear que el objeto no es nil y no se ejecuta el destructor, no hay riesgo de Acess Violation
end;

Esto funciona de maravillas y no he tenido nunca problemas con eso (una vez que lo entendi claro)

Hasta que hoy, haciendo experimentos raros, se me ocurrio hacer esto:

Código Delphi [-]
  TForm2 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    FormFoo: TObject;
  end;

procedure TForm2.Button1Click(Sender: TObject);
var
  LocalFoo: TObject;
begin
  FormFoo.Free;

  LocalFoo.Free;
end;

Obviamente llamar a FomFoo.Free es seguro, de hecho el destructor no se ejecuta; las variables de instancia son seteadas a nil en los constructores de los objetos (que va, TForm es un objeto tambien, recuerda? )

Pero el problema son las variables locales; es verdad, de hecho tiene logica, que si yo declaro una variable, y no la inicializo nunca, el valor no esta definido; es decir que una llamada a Free deberia arrojar una excepcion Acess Violation. Bueno, curiosa fue mi sorpresa al correr el codigo anterior: no se elevo ninguna excepcion.

Los invito a que ejecuten el mismo codigo

Para el que no se le ocurra, puede agregar la linea ShowMessage(LocalFoo.ClassName); antes del Free
Responder Con Cita