Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   El Destructor "destruye" las propiedades? (https://www.clubdelphi.com/foros/showthread.php?t=84624)

Comandant 13-11-2013 20:08:22

El Destructor "destruye" las propiedades?
 
Hola a todos y tengo una duda y es justamente si el destructor destruye todos los objetos y propiedades heredados o tengo que hacerlo manualmente aquí les dejo un ejemplo sencillo que veo que aun puedo acceder a la propiedad TRect.

Código:

type
  TRecuadro = class
  private
    FRect: TRect;
  public
    constructor Create;
    destructor Destroy; override;
    procedure Dibujar(Pain: TPaintBox);
    property Recta: TRect read FRect;
  end;

.....

constructor TRecuadro.Create;
begin
  inherited;
  FRect.Top:= 0;
  FRect.Bottom:= 50;
  FRect.Left:= 0;
  FRect.Right:= 50;
end;

destructor TRecuadro.Destroy;
begin
  //aqui hago manualmente la destruccion 1 x 1? pense que era automático
  inherited;
end

procedure TRecuadro.Dibujar(Pain: TPaintBox);
begin
  Pain.Canvas.Rectangle(0,0,50,50);
end;

procedure TForm1.sButton1Click(Sender: TObject);
var mar: TRecuadro;
begin
  mar:= TRecuadro.Create;
  edit1.Text:= IntToStr(mar.FRect.Right);
  mar.Dibujar(PaintBox1);
  mar.Free;
  edit2.Text:= IntToStr(mar.FRect.Right)
end;

y en el edit2 me aparece aun la propiedad. Esta bien esto?

ecfisa 13-11-2013 23:20:29

Hola Comandant.

Aunque delphi te ofrece el "azúcar sintáctico" de omitirlo, la definición completa tu clase es:
Código Delphi [-]
type
  TRecuadro = class(TObject)
   private
    FRect: TRect;
  public
    constructor Create;
    destructor Destroy; override;
    procedure Dibujar(Pain: TPaintBox);
    property Recta: TRect read FRect;
  end;
lo que indica que TRecuadro deriva de TObject, clase de la que, directa o indirectamente derivan todas las clases en Delphi.

Cuando invocas a:
Código Delphi [-]
mar.Free;
el destructor heredado se ejecutará (aún sin reescribirlo), como podrás comprobar haciendo unos pequeños cambios en tu código:
Código Delphi [-]
procedure TForm1.sButton1Click(Sender: TObject);
var mar: TRecuadro;
begin
  mar:= TRecuadro.Create;
  Edit1.Text:= mar.ClassName;  // TRecuadro
  mar.Dibujar(PaintBox1);
  mar.Free;
  edit2.Text:= mar.ClassName;  // ¡ Error !
end;
pero TObject no tiene conocimiento de las declaraciones ni la memoria que ha ocupado uno de sus descendientes, en esos casos declaras el constructor para poder liberar la memoria que ocupó el descendiente e invocar al destructor heredado. Pero en tu clase sólo hay atributos simples, no veo la necesidad de definir un constructor.

Cuando creas una instancia de clase y la liberas, el apuntador (objeto) mantiene el valor. Entonces si lo que deseas es que no se pueda acceder a ellos, tenes que asignarle nil, ya sea luego de liberarlo con Free o usando FreeAndNil en su lugar:
Código Delphi [-]
  mar.Free;
  mar := nil;

ó:
Código Delphi [-]
  FreeAndNil(mar);

Saludos :)

Comandant 14-11-2013 14:02:52

Ok entendido ahora comprendo porque muchos autores recomendaban FreeAndNil en vez de Free.
Lo que me quedo "picando" es que dijiste "Pero en tu clase sólo hay atributos simples, no veo la necesidad de definir un constructor." creo que quisiste decir un destructor? Ha y muchas gracias ecfisa siempre tan claro y atento. Te dejo puntines :-) +10

ecfisa 14-11-2013 15:19:52

Hola Comandant.
Cita:

Empezado por Comandant (Mensaje 469602)
Lo que me quedo "picando" es que dijiste "Pero en tu clase sólo hay atributos simples, no veo la necesidad de definir un constructor." creo que quisiste decir un destructor?

Así es :o, perdón por la errata.

Saludos :)


La franja horaria es GMT +2. Ahora son las 13:50:11.

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