Criar objetos dentro de um for
Pessoal me deparei com algo que nunca prescisei fazer antes:
Criar objetos dentro de um for (laço), como não sei quantos objetos vou criar uso sempre o p :TPanelAlerta;
abaixo o trecho que contem o laço:
Abaixo o método do meu objeto
Criar objetos dentro de um for (laço), como não sei quantos objetos vou criar uso sempre o p :TPanelAlerta;
abaixo o trecho que contem o laço:
var p :TPanelAlerta; begin while not CDS.Eof do begin P :=TPanelAlerta.Create(pnl); P.SetCliente(CDS.FieldByName(´ID_CLIENTE´).AsInteger, CDS.FieldByName(´DC_CLIENTE´).AsString); P.CriaEstrutura; CDS.Next; end;
Abaixo o método do meu objeto
procedure TPanelAlerta.SetCliente(ID: integer; DC: String); begin self.FIdCliente :=ID; Self.FDcCliente :=DC; end; O que está acontecendo é o seguinte como no for sempre uso o p :TPanelAlerta ele está sobreescrevendo o valor de self.FIdCliente , ou seja depois de criados todos os objetos, todos os objetos tem o mesmo valor para self.FIdCliente, sendo que na atribuição os valores são diferentes.
Diegotiemann
Curtidas 0
Respostas
Diegotiemann
24/03/2009
OBS: TPanelAlerta é um objeto que eu criei.
GOSTEI 0
Woinch
24/03/2009
Você precisará de um vetor ou array.
Para retornar um determinado objeto dentro desse array basta utilizar p[NUMERO DE ZERO ATÉ O TAMANHO -1]. Exemplos:
Para uma alternativa mais profissional, leia um pouco sobre estrutura de dados. O delphi possui uma unit chamada Contnrs, dentro existe uma classe TObjectList. Com essa classe é possível adicionar, remover, procurar objetos de uma lista de forma dinâmica.
Espero ter ajudado.
var p : array of TPanelAlerta; i : Integer; begin i := 0; while not CDS.Eof do begin SetLength(p, i +1); //aumenta o tamanho do array P[i] :=TPanelAlerta.Create(pnl); //cria o objeto no indice I do array P[i].SetCliente(CDS.FieldByName(´ID_CLIENTE´).AsInteger, CDS.FieldByName(´DC_CLIENTE´).AsString); P[i].CriaEstrutura; CDS.Next; i++; end;
Para retornar um determinado objeto dentro desse array basta utilizar p[NUMERO DE ZERO ATÉ O TAMANHO -1]. Exemplos:
ShowMessage(IntToStr(p[0].GetCliente)); //retorna o cliente (se seu objeto possuir esse método) do primeiro objeto criado. ShowMessage(IntToStr(p[0].GetCliente)); //retorna o cliente (se seu objeto possuir esse método) do segundo objeto criado. ... ShowMessage(IntToStr(p[n].GetCliente)); //retorna o cliente (se seu objeto possuir esse método) do n-ézimo objeto criado.
Para uma alternativa mais profissional, leia um pouco sobre estrutura de dados. O delphi possui uma unit chamada Contnrs, dentro existe uma classe TObjectList. Com essa classe é possível adicionar, remover, procurar objetos de uma lista de forma dinâmica.
Espero ter ajudado.
GOSTEI 0
Javapaulomg
24/03/2009
Amigo pelo oque pude entender do seu exemplo você quer uma forma de gerenciar as instâncias dos objetos que está criando, porem da forma que está fazendo a variável de referencia e sempre sobreescrita pela ultima instância criada.
Para o seu caso em especifico como o número de objetos e variável, lhe sugiro utilizar um objeto fora do for para controlar essas instâncias.
O ´TObjectList´ da unit ´Contnrs´, ira lhe auxilixar, basta criar uma instancia dele e adicionar seus objetos, e posteriormente ao destruir o mesmo ele ira destruir as instâncias contidas nele tambem, caso tenha sido inicializado como ´True´ em seu contrutor.
Caso tenha entendido errado so postar ai que olhamos. Inte+.
Para o seu caso em especifico como o número de objetos e variável, lhe sugiro utilizar um objeto fora do for para controlar essas instâncias.
O ´TObjectList´ da unit ´Contnrs´, ira lhe auxilixar, basta criar uma instancia dele e adicionar seus objetos, e posteriormente ao destruir o mesmo ele ira destruir as instâncias contidas nele tambem, caso tenha sido inicializado como ´True´ em seu contrutor.
Caso tenha entendido errado so postar ai que olhamos. Inte+.
GOSTEI 0
Javapaulomg
24/03/2009
var p : TPanelAlerta; listaObjetos : TObjectList; begin listaObjetos := TObjectList.Create(True); while not CDS.Eof do begin p := TPanelAlerta.Create(pnl); p.CriaEstrutura; listaObjetos.add(p); CDS.Next; end; FreeAndNil(listaObjetos); end;
GOSTEI 0
Diegotiemann
24/03/2009
Vou testar as duas maneiras dai dou o retorno.
GOSTEI 0
Diegotiemann
24/03/2009
Até o momento testei só a 1ª maneira (array);
Dai aconteceu algo mais estranho ainda,
para testar criei um evento ao clique do mouse no objeto
funcionou perfeitamente cada objeto mostrava seu valor
mas quanto tento acessar o valor de fora através do GetIdPaviemento, o único valor que reorna certo é o do último objeto, os outros retornaram valores aleatórios.
Dai aconteceu algo mais estranho ainda,
para testar criei um evento ao clique do mouse no objeto
showMessage(intToStr(self.FidPavimento));
funcionou perfeitamente cada objeto mostrava seu valor
mas quanto tento acessar o valor de fora através do GetIdPaviemento, o único valor que reorna certo é o do último objeto, os outros retornaram valores aleatórios.
GOSTEI 0
Woinch
24/03/2009
Como você está chamando essa função GetIdPavimento?
GOSTEI 0
Diegotiemann
24/03/2009
while not CDS.Eof do begin SetLength(p, i +1); //aumenta o tamanho do array if CDS.RecNo mod 2 =0 then pnl :=pnl1 else pnl :=pnl2; P[I] :=TPanelAlerta.Create(pnl); P[I].SetCliente(CDS.FieldByName(´ID_CLIENTE´).AsInteger, CDS.FieldByName(´DC_CLIENTE´).AsString); P[I].SetObra(CDS.FieldByName(´ID_OBRA´).AsInteger, CDS.FieldByName(´DC_OBRA´).AsString); P[I].SetPavimento(CDS.FieldByName(´ID_PAVIMENTO´).AsInteger, CDS.FieldByName(´DC_PAVIMENTO´).AsString); p[I].SetPrevisaoTermino(CDS.FieldByName(´PREVISAO_ENTREGA´).AsDateTime); p[I].SetPopUps(popProducao, popCerramica, popEPS, popFerragem, popConcretagem, popProj); P[I].CriaEstrutura; CDS.Next; end; //aqui estou chamando a função pra testar for I := 0 to CDS.RecordCount - 1 do ShowMessage(´Pavimento: ´+IntToStr(p[i].GetIdPavimento));
Alguns dos métodos do objeto:
procedure TPanelAlerta.SetPavimento(ID: integer; DC: String); begin Self.FIdPavimento :=ID; Self.FDcPavimento :=DC; end; function TPanelAlerta.GetIdPavimento: Integer; begin result :=self.FIdPavimento; end; //quando adiciono esse métono a algum evento Ex: clique do mouse, dai ele exibe o valor certo procedure TPanelAlerta.teste(sender: Tobject); begin ShowMessage(´Id Pavimento:´+IntToStr(FIdPavimento)); end;
GOSTEI 0
Diegotiemann
24/03/2009
Com o TObjectList funcionou perfeitamente.
Obrigado
Obrigado
GOSTEI 0