Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

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

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 15-02-2009
noob noob is offline
Miembro
 
Registrado: sep 2008
Posts: 212
Poder: 16
noob Va por buen camino
Duda sobre destrucción de objetos compuestos por otros objetos

Hola, me gustaría saber bien cómo destruir objetos pues aunque si no lo hago el programa funciona sin errores no me gusta ir dejando memoria sin liberar.

Yo usaba siempre Destroy para destruir objetos pero en otro hilo y en este otro de este foro me recomendaron destruir con Free aquellos objetos que no fueran hilos.

Hace poco pregunté cómo saber si un objeto estaba creado y ahí me recomendaron usar FreeAndNil(Objeto); para destruir el objeto.

Y la duda que tengo es, si tenemos un objeto con varios atributos cuyos tipos son otros objetos, yo tengo dos opciones de destruir:

1) Desde dentro de la clase del objeto:

Código Delphi [-]
destructor MiClase.Destroy; 
begin   
  FreeAndNil(Atributo1);   
  FreeAndNil(Atributo2);   
  FreeAndNil(Atributo3);   
  FreeAndNil(Atributo4); 
end;

2) Desde fuera de la clase del objeto (en otra clase que use a la anterior):

Código Delphi [-]
FreeAndNil(MiObjetoCompuesto);

En el segundo caso no implemento el método destroy en la clase MiClase y sólo llamo a FreeAndNil desde la clase externa.

¿Qué opción es la correcta? ¿Serían las dos opciones equivalentes?

Otra cosa, ¿Delphi no destruye todos los objetos creados al cerrar la aplicación?

Saludos.

Última edición por noob fecha: 15-02-2009 a las 23:00:09.
Responder Con Cita
  #2  
Antiguo 15-02-2009
Avatar de DarkMan
DarkMan DarkMan is offline
Miembro
 
Registrado: jul 2006
Posts: 102
Poder: 18
DarkMan Va por buen camino
FreeAndNil lo que hace es llamar al método Free del objeto y luego asignar la variable que apunta hacia él con "nil", después ese método free se encarga de llamar al método destroy. Es por eso que uno no quita del otro, realmente estas usando los dos con FreeAndNil.

Cita:
Otra cosa, ¿Delphi no destruye todos los objetos creados al cerrar la aplicación?
Sí, lo hace, pero ojo porque hay excepciones, espera a que alguien que sepa más del tema te comente sobre esto.
__________________
"La recompensa de una buena acción está en haberla hecho"

Última edición por DarkMan fecha: 15-02-2009 a las 17:19:28.
Responder Con Cita
  #3  
Antiguo 15-02-2009
noob noob is offline
Miembro
 
Registrado: sep 2008
Posts: 212
Poder: 16
noob Va por buen camino
Cita:
Empezado por DarkMan Ver Mensaje
... después ese método free se encarga de llamar al método destroy ...
He hecho esto:

Unit1:

Código Delphi [-]
unit Unit1; 

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Unit2;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { private declarations }
    ObjMiClase: cMiClase;
  public
    { public declarations }
  end; 

var
  Form1: TForm1; 

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  ObjMiClase := cMiClase.Create;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  FreeAndNil(ObjMiClase);
end;

end.

Unit2:

Código Delphi [-]
unit Unit2; 

interface

uses Unit3;

type
  cMiClase = class
               private
                 Obj: cMiClase2; 
               public
                 constructor Create;
                 destructor Destroy; override;
             end;

implementation

constructor cMiClase.Create;
begin
  Obj := cMiClase2.Create;
  inherited Create;
end;

destructor cMiClase.Destroy;
begin
  FreeAndNil(Obj);
  inherited Destroy;
end;

end.

Unit3:

Código Delphi [-]
unit Unit3; 

interface

type
  cMiClase2 = class
                private
                public
                  destructor Destroy;
              end;

implementation

destructor cMiClase2.Destroy;
begin
  inherited Destroy;
end;

end.

y al pulsar el botón el objeto se destruye pero no llama al método Destroy como dices.

Última edición por noob fecha: 15-02-2009 a las 22:47:50.
Responder Con Cita
  #4  
Antiguo 15-02-2009
Avatar de DarkMan
DarkMan DarkMan is offline
Miembro
 
Registrado: jul 2006
Posts: 102
Poder: 18
DarkMan Va por buen camino
Es que me da la impresión de que estas creando mal el objeto.
Aquí:
Código Delphi [-]
procedure TForm1.FormCreate(Sender: TObject);
begin
  ObjMiClase.Create;
end;

Estas creando una instancia del objeto pero no asignas su dirección de memoria a ninguna variable. Tendrías que hacer algo como:

Código Delphi [-]
ObjMiClase:= cMiClase.Create;

En este otro caso:
Código Delphi [-]
destructor cMiClase.Destroy;
begin
  FreeAndNil(Obj);
end;

Estas liberando un objeto que no has creado, por defecto apunta a "nil" así que no hay liberación. De todas formas en una clase que se destruye yo no veo necesario el uso de FreeAndNil, pero no es incorrecto. Pienso que con obj.free valdría.
__________________
"La recompensa de una buena acción está en haberla hecho"
Responder Con Cita
  #5  
Antiguo 15-02-2009
noob noob is offline
Miembro
 
Registrado: sep 2008
Posts: 212
Poder: 16
noob Va por buen camino
Cita:
Empezado por DarkMan Ver Mensaje
Es que me da la impresión de que estas creando mal el objeto.
Aquí:
Código Delphi [-]procedure TForm1.FormCreate(Sender: TObject); begin ObjMiClase.Create; end;


Estas creando una instancia del objeto pero no asignas su dirección de memoria a ninguna variable. Tendrías que hacer algo como:

Código Delphi [-]ObjMiClase:= cMiClase.Create;
Cierto, que error tan tonto, ya lo edité.

Pero FreeAndNil sigue sin llamar al método Destroy.

Última edición por noob fecha: 15-02-2009 a las 18:05:13.
Responder Con Cita
  #6  
Antiguo 15-02-2009
Avatar de DarkMan
DarkMan DarkMan is offline
Miembro
 
Registrado: jul 2006
Posts: 102
Poder: 18
DarkMan Va por buen camino
Sí que lo llama, sino te lo crees analicemos el código de cada procedimiento:

FreeAndNil:
Código Delphi [-]
procedure FreeAndNil(var Obj);
var
  Temp: TObject;
begin
  Temp := TObject(Obj);
  Pointer(Obj) := nil;
  Temp.Free;
end;

llama a Free del objeto que indiques en Obj.

Obj.free:
Código Delphi [-]
procedure TObject.Free;
begin
  if Self <> nil then
    Destroy;
end;

Aquí llama al método destroy del propio objeto.

Si te fijas, para que se llame al método destroy existe la condición de que el objeto exista:
Código Delphi [-]
...
 if Self <> nil then
...

Así que en conclusión podemos sacar que fallas también a la hora de crear ese objeto, puede que estés cometiendo el mismo error.

Edito:
en la unit2 te faltan los inherited dentro del constructor y destructor.
__________________
"La recompensa de una buena acción está en haberla hecho"

Última edición por DarkMan fecha: 15-02-2009 a las 18:29:14.
Responder Con Cita
  #7  
Antiguo 15-02-2009
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
Cita:
Empezado por DarkMan Ver Mensaje
Es que me da la impresión de que estas creando mal el objeto.
Aquí:
Código Delphi [-]
procedure TForm1.FormCreate(Sender: TObject);
begin
  ObjMiClase.Create;
end;

Estas creando una instancia del objeto pero...
Sólo aclarar que esa sintaxis (variable.constructor) no crea ninguna instancia. Invito a leer este otro hilo: http://www.clubdelphi.com/foros/show...225#post326225

Saludos.

Al González.
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
Programacion orientada a Objetos...duda total.... Kenobi Varios 20 30-07-2008 15:38:25
Objetos de sistema y otros problemas PaFernan99 Oracle 1 15-05-2008 23:16:29
Duda sobre uso de biblioteca de objetos romanuel C++ Builder 4 30-03-2008 04:22:02
Accesar a las propiedades de otros objetos sharky Varios 2 07-12-2004 23:58:55
Destrucción de objetos locales Aprendiz OOP 4 04-10-2003 00:02:03


La franja horaria es GMT +2. Ahora son las 17:53:18.


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