Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Agnaldo Francisco Mota

Problema com Delphi OOP

Recommended Posts

Olá. Programo em Delphi desde a versão 2, mas sempre usei programação procedural para desenvolver meus projetos. Depois de ter contato com C# resolvi tentar utilizar OOP no Delphi e tenho tido problemas pra me adaptar.

Criei dois objetos, como segue:

 

 

type

TState = class(TObject)

protected

FIdState: integer;

FNameState: string;

FFU: string;

public

property IdState: integer read FIdState write FIdState;

property NameState: string read FNameState write FNameState;

property FU: string read FFU write FFU;

end;

 

TStateData = class(TObject)

protected

FPassword: string;

FUserName: string;

FServer: string;

FHost: string;

public

constructor Create(Password, UserName, Server, Host: string);

function FirstReg: TState;

function LastReg: TState;

function PriorReg(IdState: integer): TState;

function NextReg(IdState: integer): TState;

end;

 

implementation

 

{TStateData}

 

constructor TStateData.Create(Password: string; UserName: string; Server: string; Host: string);

begin

FPassword := Password;

FUserName := UserName;

FServer := Server;

FHost := Host;

end;

 

function TStateData.FirstReg: TState;

var

Conexao: TConn;

spFirstReg: TADOStoredProc;

begin

Conexao := TConn.Create(FPassword, FUserName, FServer, FHost);

 

if (Conexao.Conn.Connected) then

begin

spFirstReg := TADOStoredProc.Create(nil);

with spFirstReg do

begin

Connection := Conexao.Conn;

ProcedureName := 'spEstadosFirstReg; 1';

ExecProc;

 

Open;

First;

 

while not(Eof) do

begin

result.IdState := FieldByName('IdEstado').Value;

result.NameState := FieldByName('NomeEstado').Value;

result.FU := FieldByName('UF').Value;

Next;

end;

end;

end;

 

FreeAndNil(Conexao);

FreeAndNil(spFirstReg);

end;

 

e na procedure que busca o primeiro registro da tabela fiz assim:

 

 

procedure TfrmEstados.FirstReg;

var

EstadoData: TStateData;

Estado: TState;

begin

EstadoData := TStateData.Create(frmPrincipal.Password, frmPrincipal.UserName,

frmPrincipal.Server, frmPrincipal.Host);

 

Estado := EstadoData.FirstReg;

 

PreencherCampos(Estado);

 

FreeAndNil(EstadoData);

end;

 

Existem as outras procedures para recupera o próximo registro, o anterior e o último. Aparentemente tudo funciona bem até a hora de fechar o form, quando recebo a mensagem de erro de violação de acesso. Sei que tem a ver com a instanciação ou a destruição de algum objeto, mas não faço a menor idéia de como resolver.

 

Quem puder ajudar, agradeço.

[]s,

Agnaldo

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá Agnaldo.

 

Não tenho certeza porque não conheço tanto a tecnologia que você está usando(TADOStoreProc), mas a execução do método ExecProc, não deveria vir depois do método Open lá no seu método FirstReg? Ou ainda, esses dois métodos não fazem coisas parecidas porém de maneiras diferentes?

Outra coisa, lendo na documentação do Delphi, percebi que você deve ter a propriedade Prepared setada para true antes de chamar ExecProc. Não sei se ela é possível fazer em design-time, ou se é realmente necessária mesmo.

 

Caso eu esteja errado, talvez você esteja destruindo algum objeto em uma outra função e tentando usa-lo. Talvez ocorra algo do tipo no método PreencherDados. Enfim, Access Violation acontece mais frequentemente quando um objeto foi destruído e você está tentando usa-lo, ou quando você tenta acessar um objeto que nem foi instanciado.

 

Além disso, não sei toda a lógica do seu programa, mas se o método FirstReg deveria retornar apenas o primeiro registro, porque ele percorre todos os dados? Isso é, seu while not (EOF) e a execução do método Next?

 

:D

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá Agnaldo.

 

Não tenho certeza porque não conheço tanto a tecnologia que você está usando(TADOStoreProc), mas a execução do método ExecProc, não deveria vir depois do método Open lá no seu método FirstReg? Ou ainda, esses dois métodos não fazem coisas parecidas porém de maneiras diferentes?

Outra coisa, lendo na documentação do Delphi, percebi que você deve ter a propriedade Prepared setada para true antes de chamar ExecProc. Não sei se ela é possível fazer em design-time, ou se é realmente necessária mesmo.

 

Caso eu esteja errado, talvez você esteja destruindo algum objeto em uma outra função e tentando usa-lo. Talvez ocorra algo do tipo no método PreencherDados. Enfim, Access Violation acontece mais frequentemente quando um objeto foi destruído e você está tentando usa-lo, ou quando você tenta acessar um objeto que nem foi instanciado.

 

Além disso, não sei toda a lógica do seu programa, mas se o método FirstReg deveria retornar apenas o primeiro registro, porque ele percorre todos os dados? Isso é, seu while not (EOF) e a execução do método Next?

 

:D

 

Olá Fernando.

Após a execução do ADOStoredProc, os dados de retorno fazem ele se comportar como uma tabela, por isso do método Open. E eu percorro a "tabela" para poder recuperar os dados nela. Eu tentei fazer da forma que parecia a correta: só executar o ExecProc e ler o retorno, mas só consegui os dados dessa forma.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Entendi. Poderia dizer quando exatamente lança a mensagem de erro? Em qual método?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Entendi. Poderia dizer quando exatamente lança a mensagem de erro? Em qual método?

Quando eu encerro o formulário. Tudo funciona muito bem, até a hora que resolvo fechar o formulário filho e voltar ao formulário principal.

To desistindo dessa história de OOP no Delphi. Se quiser fazer isso vou ter de ir ao C# mesmo.

Compartilhar este post


Link para o post
Compartilhar em outros sites
To desistindo dessa história de OOP no Delphi. Se quiser fazer isso vou ter de ir ao C# mesmo.

 

Cara, a orientação a objetos será sempre a mesma, a diferença será a sintaxe da linguagem de programação diferente ou seu suporte a Orientação a Objetos. Se o erro está sendo lançado, é porque há algo errado, e todo problema pode ser resolvido. Mas lembre-se, o problema não é a linguagem.

 

O Object Pascal(Delphi) é uma ótima linguagem de programação, que acredito eu, muito mais leve e rápida que o C#, pois já criei um projeto muito simples em C#, e não gostei muito da performance. Eu gosto de C#, mas não sei porque todo mundo prefere ela hoje em dia. Talvez o marketing conceituou ela. Mas existem diversas linguagens que dão ótimo suporte a Orientação a Objetos e que são mais direcionadas para programas em Desktop. O próprio PHP se não me engano, tem uma versão para Desktop.

Enfim, no final das contas, será tudo a mesma coisa em relação a isso.

 

Uma pergunta, você está debugando seu projeto? O ideal seria você debugar linha por linha próximo onde o seu programa está lançando o erro, pois não tenho como saber o que está acontecendo quando você fecha essa formulário filho. De repente, após você fechar esse formulário filho, talvez você esteja querendo chamar ele, ou outro objeto que já foi destruído e você também queira estar chamando ele. Tente passar mais informações do seu problema, inclusive o código em que está acontecendo isso.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Cara, a orientação a objetos será sempre a mesma, a diferença será a sintaxe da linguagem de programação diferente ou seu suporte a Orientação a Objetos. Se o erro está sendo lançado, é porque há algo errado, e todo problema pode ser resolvido. Mas lembre-se, o problema não é a linguagem.

 

O Object Pascal(Delphi) é uma ótima linguagem de programação, que acredito eu, muito mais leve e rápida que o C#, pois já criei um projeto muito simples em C#, e não gostei muito da performance. Eu gosto de C#, mas não sei porque todo mundo prefere ela hoje em dia. Talvez o marketing conceituou ela. Mas existem diversas linguagens que dão ótimo suporte a Orientação a Objetos e que são mais direcionadas para programas em Desktop. O próprio PHP se não me engano, tem uma versão para Desktop.

Enfim, no final das contas, será tudo a mesma coisa em relação a isso.

 

Uma pergunta, você está debugando seu projeto? O ideal seria você debugar linha por linha próximo onde o seu programa está lançando o erro, pois não tenho como saber o que está acontecendo quando você fecha essa formulário filho. De repente, após você fechar esse formulário filho, talvez você esteja querendo chamar ele, ou outro objeto que já foi destruído e você também queira estar chamando ele. Tente passar mais informações do seu problema, inclusive o código em que está acontecendo isso.

 

Eu já verifiquei todos os objetos. A exceção é lançada no momento que ele executa o método Close. A parte fácil de trabalhar com C# e Java é o garbage collection que o Delphi não tem, aí dá esses paus. você olha o código todo. Jura que tá fechando todos os objetos, mas alguma coisa escapa e o programa não roda.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Desculpa cara, mas não faço idéia qual será o problema agora. Talvez seja alguma dependência desse formulário que esteja causando isso. Ou talvez tenha algo no evento OnClose do formulário.

 

A parte fácil de trabalhar com C# e Java é o garbage collection que o Delphi não tem, aí dá esses paus.

 

Mas nisso concordo com você, essas outras linguagens cuidam para nós a questão de gerenciamento de memória, destruição dos objetos, etc. Quase todo dia eu tenho problemas com Acess Violation, e muitas das vezes, é por causa disso aí.

 

Desculpa não conseguir ajudar. Mas caso você consiga resolver, poste a solução para nós.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Quando eu encerro o formulário. Tudo funciona muito bem, até a hora que resolvo fechar o formulário filho e voltar ao formulário principal.

To desistindo dessa história de OOP no Delphi. Se quiser fazer isso vou ter de ir ao C# mesmo.

Poderia postar o código que encerra o formulário?

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.