devo usar FreeAndNil ou Destructor Destroi?

10/04/2006

Estou iniciando em Orientação a Objetos e me deparei com uma dúvida. Suponham a minha classe abaixo:

Type
TFaltas = Class(TObject)
MeuMemo : TMemo;
NumeroDeFaltas : Integer;
Constructor Cria;
Destructor Destroi;
End;

Var
UmaFalta : TFalta;
.
.
.
Implementation
Constructor TFaltas.Cria;
Begin
MeuMemo := TMemo.Create;
NumeroDeFaltas := 0;
End;

Destructor TFaltas.Destroi;
Begin
FreeAndNil(MeuMemo);
End;
.
.
.
{Chamando o construtor e o destruidor}

Procedure UsaOObjeto;
Begin
UmaFalta := TFalta.Create;
{agora vem a dúvida: o que uso para liberar o objeto?}
UmaFalta.Destroi;
UmaFalta.Free ou
FreeAndNil(UmaFalta);
End;

Então fico na dúvida de que método usar para liberar o objeto. Sei que se minha classe não contivesse nenhum outro objeto na sua definição, o ideal seria usar FreeAndNil, mas UmaFalta cria um outro objeto dentro dele (um memo) no momento em que é instanciado. Nessas condições, como devo liberar da memória o objeto UmaFalta?
Agradeço o interesse.


Cherodogo

Respostas

10/04/2006

Massuda

Algumas padronizações do Delphi...[list:4d720670d7][*:4d720670d7]O construtor sempre chama-se Create.[*:4d720670d7]O destrutor sempre chama-se Destroy[*:4d720670d7]Para destruir um objeto, use Free; evite chamar Destroy diretamente.[/list:u:4d720670d7]
Embora Delphi permita você ter construtor/destrutor com qualquer nome, geralmente código para Delphi assume que o construtor/destrutor usam os nomes padrão.

Use sempre Free (ou FreeAndNil) ao invés de Destroy. Free verifica se o objeto a ser liberado é ou não nil (embora não verifique se o objeto já foi destruído), coisa que Destroy não faz.

Free e FreeAndNil fazem basicamente a mesma coisa, o diferencial é que FreeAndNil irá atribuir nil à referencia ao objeto que você está liberando. Isso é útil no caso de objetos de escopo global, mas não faz diferença no caso de objetos de escopo local.


Responder Citar

10/04/2006

Lorde_morte.

o diferencial é que FreeAndNil irá atribuir nil à referencia ao objeto que você está liberando. Isso é útil no caso de objetos de escopo global, mas não faz diferença no caso de objetos de escopo local.


Apesar de FreeAndNil ser um pouco maior do que Free eu sempre uso o FreeAndNil.


Responder Citar

10/04/2006

Cherodogo

Algumas padronizações do Delphi...[list:993002c252][*:993002c252]O construtor sempre chama-se Create.[*:993002c252]O destrutor sempre chama-se Destroy[*:993002c252]Para destruir um objeto, use Free; evite chamar Destroy diretamente.[/list:u:993002c252] Embora Delphi permita você ter construtor/destrutor com qualquer nome, geralmente código para Delphi assume que o construtor/destrutor usam os nomes padrão. Use sempre Free (ou FreeAndNil) ao invés de Destroy. Free verifica se o objeto a ser liberado é ou não nil (embora não verifique se o objeto já foi destruído), coisa que Destroy não faz. Free e FreeAndNil fazem basicamente a mesma coisa, o diferencial é que FreeAndNil irá atribuir nil à referencia ao objeto que você está liberando. Isso é útil no caso de objetos de escopo global, mas não faz diferença no caso de objetos de escopo local.


Ok, Massuda. Mas a minha dúvida ainda é se, usando FreeAndNil(UmaFalta), o memo que faz parte deste meu objeto também será liberado automaticamente.
Abraço.


Responder Citar

10/04/2006

Cherodogo

Algumas padronizações do Delphi...[list:634c2706d7][*:634c2706d7]O construtor sempre chama-se Create.[*:634c2706d7]O destrutor sempre chama-se Destroy[*:634c2706d7]Para destruir um objeto, use Free; evite chamar Destroy diretamente.[/list:u:634c2706d7] Embora Delphi permita você ter construtor/destrutor com qualquer nome, geralmente código para Delphi assume que o construtor/destrutor usam os nomes padrão. Use sempre Free (ou FreeAndNil) ao invés de Destroy. Free verifica se o objeto a ser liberado é ou não nil (embora não verifique se o objeto já foi destruído), coisa que Destroy não faz. Free e FreeAndNil fazem basicamente a mesma coisa, o diferencial é que FreeAndNil irá atribuir nil à referencia ao objeto que você está liberando. Isso é útil no caso de objetos de escopo global, mas não faz diferença no caso de objetos de escopo local.


Ok, Massuda. Mas a minha dúvida ainda é se, usando FreeAndNil(UmaFalta), o memo que faz parte deste meu objeto também será liberado automaticamente.
Abraço.


Responder Citar

10/04/2006

Massuda

...usando FreeAndNil(UmaFalta), o memo que faz parte deste meu objeto também será liberado automaticamente.
Não. Se você criou um objeto dentro do seu (vou chamar de ´objeto interno´), geralmente é usa responsabilidade liberar esse objeto interno no destrutor do seu objeto.

No seu código original você até fez isso (me desculpe se foi erro de digitação), mas como voicê chamou o destrutor de Destroi, esse destrutor não é executado pelo Free ou FreeAndNil, já que essas funções assumem que o destrutor do objeto chama-se Destroy.

A VCL do Delphi tem um mecanismo diferente de decidir quem deve liberar um objeto baseado no Owner (se você olhar nas classes da VCL verá que várias delas preveem no construtor quem é o Owner - dono - do objeto). Nesse caso, é responsabilidade do Owner destruir o objeto.


Responder Citar

10/04/2006

Cherodogo

[quote:a265d502bb=´CheroDoGo´]...usando FreeAndNil(UmaFalta), o memo que faz parte deste meu objeto também será liberado automaticamente.
Não. Se você criou um objeto dentro do seu (vou chamar de ´objeto interno´), geralmente é usa responsabilidade liberar esse objeto interno no destrutor do seu objeto.

No seu código original você até fez isso (me desculpe se foi erro de digitação), mas como voicê chamou o destrutor de Destroi, esse destrutor não é executado pelo Free ou FreeAndNil, já que essas funções assumem que o destrutor do objeto chama-se Destroy.

A VCL do Delphi tem um mecanismo diferente de decidir quem deve liberar um objeto baseado no Owner (se você olhar nas classes da VCL verá que várias delas preveem no construtor quem é o Owner - dono - do objeto). Nesse caso, é responsabilidade do Owner destruir o objeto.[/quote:a265d502bb]

Quer dizer então, que, se eu trocar o nome do meu destruidor e chamá-lo de Destructor Destroy, o FreeAndNil(UmaFalta) vai liber o objeto UmaFalta e o objeto Memo que está dentro dele também?

Type
TFaltas = Class(TObject)
MeuMemo : TMemo;
NumeroDeFaltas : Integer;
Constructor Create;
Destructor Destroy;
End;

Var
UmaFalta : TFalta;
.
.
.
Implementation
Constructor TFaltas.Create;
Begin
MeuMemo := TMemo.Create;
NumeroDeFaltas := 0;
End;

Destructor TFaltas.Destroy;
Begin
FreeAndNil(MeuMemo);
End;
.
.
.
{Chamando o construtor e o destruidor}

Procedure UsaOObjeto;
Begin
UmaFalta := TFalta.Create;
{agora vem a dúvida: o que uso para liberar o objeto?}
UmaFalta.Destroy; //com y no final (risos)
UmaFalta.Free ou
FreeAndNil(UmaFalta);
End;

Valeu, Massuda!


Responder Citar

10/04/2006

Massuda

...se eu trocar o nome do meu destruidor e chamá-lo de Destructor Destroy, o FreeAndNil(UmaFalta) vai liber o objeto UmaFalta e o objeto Memo que está dentro dele também?
Sim porque o destrutor que você escreveu faz isso. E isso vai ocorrer tanto no caso de você usar Free ou FreeAndNil.

Um detalhe importante é que o destrutor Destroy é virtual, o que significa que você deve declarar seu destrutor Destroy com override e incluir um inherited como sendo a última linha do seu destrutor...
Type 
  TFaltas = Class(TObject) 
    ...
    Destructor Destroy; override;
    ...
  end;

Destructor TFaltas.Destroy; 
Begin 
  FreeAndNil(MeuMemo); 
  inherited;
End; 

{Chamando o construtor e o destruidor} 

Procedure UsaOObjeto; 
Begin 
  UmaFalta := TFalta.Create; 
  ...
  UmaFalta.Free
ou 
  FreeAndNil(UmaFalta); 
End;



Responder Citar

10/04/2006

Adriano Santos

Só uma correção no constructor. A assinatura ´correta´ é:

Type
  TFaltas = Class(TObject)
    MeuMemo : TMemo;
    NumeroDeFaltas : Integer;
    constructor Create(AOWner: TObject);override;
    destructor destroy;override;
  End; 



[b:a0bae13f11]Massuda[/b:a0bae13f11], me corrija se eu estiver incorreto. O override diz ao compilador que o [b:a0bae13f11]create[/b:a0bae13f11] e o [b:a0bae13f11]destructor[/b:a0bae13f11] pode ser sobrepostos correto?


Responder Citar

10/04/2006

Cherodogo

Cara, valeu mesmo. Muito obrigado, Massuda. Baita mão na roda. Já aprendi um pouco mais de POO contigo.
Abraço.


Responder Citar

10/04/2006

Massuda

[quote:f0cef875ac=´Adriano Santos´]O override diz ao compilador que o [b:f0cef875ac]create[/b:f0cef875ac] e o [b:f0cef875ac]destructor[/b:f0cef875ac] pode ser sobrepostos correto?[/quote:f0cef875ac]Acho que o mais correto é interpretar o [b:f0cef875ac]override[/b:f0cef875ac] como sendo ´o construtor/destrutor/método [b:f0cef875ac]foi[/b:f0cef875ac] sobreposto´. Note que [b:f0cef875ac]virtual[/b:f0cef875ac] pode ser interpretado como sendo ´o construtor/destrutor/método [b:f0cef875ac]pode ser[/b:f0cef875ac] sobreposto´

[quote:f0cef875ac=´Adriano Santos´]constructor Create(AOWner: TObject);override;
[/quote:f0cef875ac]No caso, como TFaltas é derivado de TObject, o código original é correto. Sua sugestão seria válida se TFaltas fosse derivado, no caso de classes da VCL, de TComponent.


Responder Citar

10/04/2006

Adriano Santos

[quote:81c3fbd8aa=´Adriano Santos´]O override diz ao compilador que o [b:81c3fbd8aa]create[/b:81c3fbd8aa] e o [b:81c3fbd8aa]destructor[/b:81c3fbd8aa] pode ser sobrepostos correto?
Acho que o mais correto é interpretar o [b:81c3fbd8aa]override[/b:81c3fbd8aa] como sendo ´o construtor/destrutor/método [b:81c3fbd8aa]foi[/b:81c3fbd8aa] sobreposto´. Note que [b:81c3fbd8aa]virtual[/b:81c3fbd8aa] pode ser interpretado como sendo ´o construtor/destrutor/método [b:81c3fbd8aa]pode ser[/b:81c3fbd8aa] sobreposto´

[quote:81c3fbd8aa=´Adriano Santos´]constructor Create(AOWner: TObject);override;
[/quote:81c3fbd8aa]

No caso, como TFaltas é derivado de TObject, o código original é correto. Sua sugestão seria válida se TFaltas fosse derivado, no caso de classes da VCL, de TComponent.[/quote:81c3fbd8aa]

Ah, entendi tudo agora...vlw


Responder Citar

12/04/2006

Fabiano Góes

Caraca, esse é mesmo o melhor forum Delphi do planeta.

Caras como Massuda, Adriano Santos, Martins, Rjun e muitos outros
sempre dando a maior força.

Ai brother vcs são firmeza mesmo !!!!

Espero um dia ter pelo menos um pouco do conhecimento que vcs tem,
pra poder ajudar aqui no forum tambem !!!!

Um grande abraço !!!!!


Responder Citar

12/04/2006

Martins

[quote:2f3de0d39d=´Fabiano Góes´]Caraca, esse é mesmo o melhor forum Delphi do planeta.

Caras como Massuda, Adriano Santos, Martins, Rjun e muitos outros
sempre dando a maior força.

Ai brother vcs são firmeza mesmo !!!!

Espero um dia ter pelo menos um pouco do conhecimento que vcs tem,
pra poder ajudar aqui no forum tambem !!!!

Um grande abraço !!!!![/quote:2f3de0d39d]

Realmente tem muitos colegas bons em desenvolvimento.
[quote:2f3de0d39d=´Fabiano Góes´]
Caras como Massuda, Adriano Santos, Martins, Rjun e muitos outros
sempre dando a maior força.
[/quote:2f3de0d39d]

eu sou um mero aprendiz ainda, mas todos concordam q o [b:2f3de0d39d]Massuda[/b:2f3de0d39d] é um dos muitos gurus deste fórum, q conta com a participação de bons profissionais.

[quote:2f3de0d39d=´Fabiano Góes´]
Espero um dia ter pelo menos um pouco do conhecimento que vcs tem,
pra poder ajudar aqui no forum tambem !!!!
[/quote:2f3de0d39d]

Com certeza vc chegará ao seu objetivo, com dedicação vc conseguirá.

Boa sorte!


Responder Citar

13/04/2006

Adriano Santos

[quote:56f21f2ea4=´Fabiano Góes´]...Adriano Santos...[/quote:56f21f2ea4]

Heheh, obrigado por citar meu nome Fabiano, é bom ter o reconhecimento da galera. Tb sou um mero espectador, e como aprendi muito aqui, e continuo aprendendo, faço questão de ajudar a todos. Fiz muitos amigos no fórum, e com vc não será diferente. Pode contar comigo.


Um forte abraço


Responder Citar

13/04/2006

Fabiano Góes

Olha só pessoal, eu citei apenas alguns nomes que me vieram na cabeça na hora, alguns caras que já me ajudaram ( Aroldo Zanela, Marcos Salles, Gandalf, Afarias )porem não queria ser injusto com ninguem, pois se for descrever todos os nomes dos caras que se dedicam a ajudar a galera a lista seria enorme, mais como já citei alguns tem um cara que poderia ficar de fora que é o ´Michael´ que alem de ajudar com o problema entra em uns detales didaticos muito importantes.

Em fim, o que eu queria dizer é que esse realmente é o melhor forum do Brasil se não do planeta.

Valeu ai pessoal !!!!
Boa Pascoa pra todos !!!!!!


Responder Citar