devo usar FreeAndNil ou Destructor Destroi?

Delphi

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

Cherodogo

Curtidas 0

Respostas

Massuda

Massuda

10/04/2006

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.


GOSTEI 0
Lorde_morte.

Lorde_morte.

10/04/2006

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.


GOSTEI 0
Cherodogo

Cherodogo

10/04/2006

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.


GOSTEI 0
Cherodogo

Cherodogo

10/04/2006

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.


GOSTEI 0
Massuda

Massuda

10/04/2006

...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.


GOSTEI 0
Cherodogo

Cherodogo

10/04/2006

[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!


GOSTEI 0
Massuda

Massuda

10/04/2006

...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;



GOSTEI 0
Adriano Santos

Adriano Santos

10/04/2006

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?


GOSTEI 0
Cherodogo

Cherodogo

10/04/2006

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


GOSTEI 0
Massuda

Massuda

10/04/2006

[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.


GOSTEI 0
Adriano Santos

Adriano Santos

10/04/2006

[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


GOSTEI 0
Fabiano Góes

Fabiano Góes

10/04/2006

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 !!!!!


GOSTEI 0
Martins

Martins

10/04/2006

[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!


GOSTEI 0
Adriano Santos

Adriano Santos

10/04/2006

[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


GOSTEI 0
Fabiano Góes

Fabiano Góes

10/04/2006

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 !!!!!!


GOSTEI 0
Adriano Santos

Adriano Santos

10/04/2006

[quote:c6e4a90e01=´Fabiano Góes´]
Em fim, o que eu queria dizer é que esse realmente é o melhor forum do Brasil se não do planeta.[/quote:c6e4a90e01]

Pode crer Fabiano, olha desde quando eu sou cadastrado, puts meu...sou viciado nisso...hehehe...


GOSTEI 0
POSTAR