Fórum Duvida sobre POO #329810

21/09/2006

0

Salve galera,

bom tenho a seguinte duvida:

se dentro e uma classe tenho alguns métodos que criam objetos: TADOConnection, TADOQuery etc.

quando eu destruir( destructor ) essa classe ( TClasse.Free; ) os objetos tambem serao destruidos ????


Fabiano Góes

Fabiano Góes

Responder

Posts

21/09/2006

Massuda

[quote:2e74780374=´Fabiano Góes´]quando eu destruir( destructor ) essa classe ( TClasse.Free; ) os objetos tambem serao destruidos ????[/quote:2e74780374]Geralmente não, é responsabilidade de quem criou um objeto destruir o objeto quando ele não for mais necessário.

A exceção é um mecanismo da VCL para classes derivadas de TComponent (geralmente itens visuais) que implementa a destruição automática dos objetos que são possuídos por outro (através da propriedade Owner).


Responder

Gostei + 0

21/09/2006

Marco Salles

se é que eu entendi bem , sua duvida , acho que nao é aconelhavel , usar os metodo de uma classe para criar objetos de outras classes

O correto é que esses objetos façam parte do atributos desta classes e devam ser instanciados no constructor e destruidos no destructor desta calsse

Tipo isto

Type TminhaClass = class(.... private var objeto1:TObjeto1; objeto2:TObjeto2; etc... public constructor create; desTructor Destroy; outros metodos.... end;


implementation

constructor TminhaClass.Create; begin objeto1:TObjeto1,Create; objeto2:TObjeto2.Create; et.... end;


Destructor TminhaClass; begin objeto1.free; objeto2.free; end



Responder

Gostei + 0

21/09/2006

Fabiano Góes

Beleza, entendi !!!!
Valeu Massuda e Marcos Salles !!!!

aproveitando a situação,

qual a diferença:
TClasse.Free <-> FreeAndNil( TClasse ) ?



Responder

Gostei + 0

21/09/2006

Marco Salles

veja , na minha opinião , ate observei que voce postou , não se existe

TClasse.Free <-> FreeAndNil( TClasse )


metodos são apliclados as objetos de uma classe ...,. existem tb ,metodos de classe , (com é o caso de constructor e descturctor) mas acho que este não é o seu caso

mas vamos supor que voce faça:
var
umObjeto:TMinhaClasse;
begin
UmObjeto:=TminhaClasse.Create;
umObjeto.Free;
ou
FreeandnIL(UmObjeto)

o metodo free não configura o objeto como nil... Dentro do metodo free , conhecemos o endereço da memoria do objeto criado <objeto Instanciado > , mas não conhecemos a posicao da memoria da variavel ( var umObjeto) que esta fazendo referencia ao Objeto.. Portanto o metodo free não pode afetar a variavel e configura-la como nil

Ao chamarmos um procedimento externo como o FreeandNil , ele sabe sobre a referencia (var) ao Objeto e pode atuar sobre esta referencia configurando-a como nil

em outras palavras

FreeandNil(meuObjeto) = MeuObjeto.Free + MeuObjeto:=nil



Responder

Gostei + 0

21/09/2006

Massuda

Ambos fazem a mesma coisa

SeuObjeto.Free

* funciona mesmo se SeuObjeto = nil (na verdade, quando SeuObjeto = nil, não faz nada )
* depois de executado, SeuObjeto <> nil e é inválido

FreeAndNil(SeuObjeto)

* falha se SeuObjeto = nil
* depois de executado, SeuObjeto = nil


Responder

Gostei + 0

21/09/2006

Fabiano Góes

Valeu Massuda e Marco Salles,

obrigado pela atenção !!!!


Responder

Gostei + 0

21/09/2006

Marco Salles

uma coisa importante que foi colocado Fabiano Góes é que free não configura o Objeto como nil , mas torna o Ponteiro inválido

* depois de executado, SeuObjeto <> nil e é inválido


é um pequeno detalhe , mas acho notável

veja

meuObjeto.Free; if meuObjeto <> nil then meuObjeto.SeuMetodo; **** //o teste sera satisfeito e teremos um erro nesta Linha



Responder

Gostei + 0

21/09/2006

Michael

[quote:af17744c81=´Marcos Salles´]se é que eu entendi bem , sua duvida , acho que nao é aconelhavel , usar os metodo de uma classe para criar objetos de outras classes.
O correto é que esses objetos façam parte do atributos desta classes e devam ser instanciados no constructor e destruidos no destructor desta calsse [/quote:af17744c81]
Isso depende, [b:af17744c81]Marcos Salles[/b:af17744c81]. Há casos onde a criação de um objeto é custosa e só deve ser feita qdo realmente necessário. É o caso de um acesso a um banco de dados.

Nessas situações, uma best practice é inicializar a variável com nil no construtor da classe, e no método que a utiliza, verificar a sua nulidade e instanciar o objeto de fato. No destrutor, ao chamar Free, não ocorrerá erro mesmo que o ponteiro ainda esteja nulo.

Ambos fazem a mesma coisa

Na verdade, [b:af17744c81]Free [/b:af17744c81]e [b:af17744c81]FreeAndNil [/b:af17744c81]têm funções diferentes. Enquanto [b:af17744c81]Free [/b:af17744c81]verifica a nulidade do objeto e chama o seu destrutor caso a instância seja diferente de nil, [b:af17744c81]FreeAndNil [/b:af17744c81]chama [b:af17744c81]Free [/b:af17744c81]e depois anula o ponteiro da variável do objeto (tecnicamente falando não ocorre nessa ordem, mas o efeito prático é o mesmo).

FreeAndNil(SeuObjeto) * falha se SeuObjeto = nil * depois de executado, SeuObjeto = nil

[b:af17744c81]FreeAndNil [/b:af17744c81]não falha mesmo que o objeto seja nil, pois ele chama [b:af17744c81]Free[/b:af17744c81], que faz o teste de nulidade mencionado anteriormente.


Responder

Gostei + 0

21/09/2006

Fabiano Góes

[quote:d0d7b4dbcd=´Marco Salles´]uma coisa importante que foi colocado Fabiano Góes é que free não configura o Objeto como nil , mas torna o Ponteiro inválido

* depois de executado, SeuObjeto <> nil e é inválido


é um pequeno detalhe , mas acho notável

veja

meuObjeto.Free; if meuObjeto <> nil then meuObjeto.SeuMetodo; **** //o teste sera satisfeito e teremos um erro nesta Linha
[/quote:d0d7b4dbcd]

Marco Salles,
foi justamente um caso como este que me levou a fazer este post,

depois de usar
 MeuObjeto.Free; 


em outra parte do codigo eu fazia um teste:
if MeuObjeto = nil then //<- aqui o teste era falso
  MeuObjeto.Create;  // se era falso nao entrava  

MeuObjeto.Metodo;   //<- aqui gerava um erro pois o "Free" nao tinha
                    // configurado o o Objeto com nil apenas tornou o 
                    // ponteiro inválido


mais agora ficou claro :D

valeu !!!


Responder

Gostei + 0

21/09/2006

Siam

Aproveitando o assunto, Free testa se o objeto é nil e se não for executa o Destroy. Se der Free 2 vezes, pode dar erro na segunda vez ?


Responder

Gostei + 0

21/09/2006

Michael

Aproveitando o assunto, Free testa se o objeto é nil e se não for executa o Destroy. Se der Free 2 vezes, pode dar erro na segunda vez ?

Sim. Podem ocorrer desde um erro de operação de ponteiro inválida ([b:e70dd92ead]Invalid pointer operation[/b:e70dd92ead]) até uma violação de acesso ([b:e70dd92ead]Access violation[/b:e70dd92ead]), pois o método [b:e70dd92ead]Free [/b:e70dd92ead]não pertencerá mais a uma instância válida do objeto.

Entretanto, pode-se chamar [b:e70dd92ead]FreeAndNil [/b:e70dd92ead]inúmeras vezes e estes erros não irão acontecer.

[]´s


Responder

Gostei + 0

21/09/2006

Fabiano Góes

Aproveitando esse post que é sobre POO, tenho mais uma duvida:

Exemplo:
Tenho uma classe
TPai = class
//que tem o metodo:
Constructor Create( aParam: AlgumTipo );


e uma classe
TFilha = class( TPai )

aqui esta a minha duvida:
[b:33864a0647]Tem como criar o metodo costructor da classe Filha com parametros
diferentes da classe Pai e que execute o constructor da class Pai ?[/b:33864a0647]

exemplo:
constructor TFilha.Create ( aParam1, aParam2: OutroTipo );
begin
  inherited; // executa o constructor da classe Pai
  // ...
  // ...
end;



Responder

Gostei + 0

21/09/2006

Michael

[quote:e8342319c5=´Fabiano Góes´]Tem como criar o metodo costructor da classe Filha com parametros
diferentes da classe Pai e que execute o constructor da class Pai ?[/quote:e8342319c5]
Sim. Apenas defina na classe filha o novo construtor desejado, exatamente como no exemplo que vc mesmo fez. A única coisa que não vai funcionar é a chamada a [b:e8342319c5]inherited [/b:e8342319c5]no construtor da classe filha, pois, como os parâmetros são diferentes, o compilador do Delphi não tem como saber como montar a assinatura do método na classe pai. Então vc tem que chamá-lo explicitamente:

constructor TFilha.Create(aParam1, aParam2: OutroTipo);
begin
  inherited Create(AlgumTipo); // executa o constructor da classe Pai 
...
end;


Se o construtor da classe-pai estiver marcado com a palavra-chave [b:e8342319c5]virtual[/b:e8342319c5], vc deve marcar o mesmo método na classe filha com a palavra-chave [b:e8342319c5]reintroduce[/b:e8342319c5], para remover o warning que o compilador vai gerar.

[]´s


Responder

Gostei + 0

22/09/2006

Marco Salles

Marcos Salles escreveu: se é que eu entendi bem , sua duvida , acho que nao é aconelhavel , usar os metodo de uma classe para criar [b:2004bc055d]objetos de outras classes. [/b:2004bc055d]O correto é que esses objetos façam parte do atributos desta classes e devam ser instanciados no constructor e destruidos no destructor desta calsse [quote:2004bc055d]Isso depende, Marcos Salles. Há casos onde a criação de um objeto é custosa e só deve ser feita qdo realmente necessário. É o caso de um acesso a um banco de dados. Nessas situações, uma best practice é inicializar a variável com nil no construtor da classe, e no método que a utiliza, verificar a sua nulidade e instanciar o objeto de fato. No destrutor, ao chamar Free, não ocorrerá erro mesmo que o ponteiro ainda esteja nulo.
[/quote:2004bc055d]

particularidades e situaçoes que merecem atenção especial , sempre irão existir... Quando coloquei o modelo simplificado , foi na[b:2004bc055d] percepeção [/b:2004bc055d]que tive da pergunta do Fabiano.Goes e que vejo muita gente fazendo

Type TMinhaClasse = class .... public Constructor Create end;


No metodo constructor

Constructor MinhaClasse.Create; begin //o cara instancia um objeto de outra classe ... [b:2004bc055d]//não tem nenhum atributo na classe com relação[/b:2004bc055d] //a estes objetos umObjetoDeOutraClasse:=TOutraClasse.Cretae; end;


Var umObjetoMinhaClasse:TminhaClasse; begin umObjetoMinhaClasse:=TumObjetoMinhaClasse.Create; Aqui o cara destroe o objeto umObjetoMinhaClasse.Free; end;


a questão é:
quando eu destruir( destructor ) essa classe ( TClasse.Free; ) os objetos tambem serao destruidos ????


A resposta na minha opnião é não.. O objeto criado <umObjetoDeOutraClasse> ainda estara na memoria

esta foi a minha[b:2004bc055d] abstração [/b:2004bc055d]da duvida do Fabiano.Goes... Aonde tive como principal foco a parte dos[b:2004bc055d] Atributos [/b:2004bc055d]da Classe e não a localização em si da [b:2004bc055d]criação[/b:2004bc055d] desses Objetos.

é claro que este objetos serão na maior parte das vezes intanciados no metodo contructor da classe , mas voce apresentou um modelo , aonde por questões ´custodiosas´ , esta instanciação se dara num método da classe... Isto é , so ira instanciar , quando de fato necessitar desses objetos

Outro fato importante em sua colocação foi:

[b:2004bc055d]michael escreveu[/b:2004bc055d]
No destrutor, ao chamar Free, não ocorrerá erro mesmo que o ponteiro ainda esteja nulo.


porque mesmo que seja nil , se trata de um ponteiro válido...



O seu modelo veio a completar a minha opinião , e é bom que fique entendido , pois esses topicos são referencias para consultas posteriores. Portanto não podemos deixar um Grual de dúvida e nem de incertezas.


Responder

Gostei + 0

24/09/2006

Thomaz_prg

Também estou estudando um pouco de POO e ficaram algumas dúvidas com relação ao tópico, e gostaria da ajuda dos colegas...

1. Tipo, li em alguns artigos, que não é correto se ter nas classes objetos de ligação com o banco de dados... essa afirmação procede?

2. Como ficaria a montagem de uma classe, para a montagem de uma pesquisa por exemplo???

3. Li a respeito de campos de classe, porém não encontrei uma forma de fazer isso no delphi (7 pelo menos, pois no 2006 vi um exemplo, que testei no delphi 7 e não funcionou). Alguém saberia como implementar isso??

4. A respeito da utilização de classes e interface com o usuário... acham viável a utilização de ferramentas do tipo SnapDataset?? Ou preferem trabalhar com TFields??? Ou trabalhar apenas com a classe e componentes não dataaware? E pq?

5. Como ficaria o trabalho da criação das classes, na montagem de uma aplicação multicamadas (3 ou 4 camadas). As classes ficariam no cliente, na aplicação servidora ou em ambos?

Desculpem pelo excesso... sei que é muita coisa, mas é que, não sei muito sobre a área. Hoje, procuro implementar o que acredito ser mais ou menos correto, sobre POO, usando TFields, e componentes dataaware. Deixo as regras todas nos componentes. Mas não sei até que ponto isso está correto.


Responder

Gostei + 0

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar