Criar lista do tipo CArrayList<T> com os dados de minha classe

 

Estou tentando implementar uma lista   CArrayListcom alguns dados do tipo   CPessoa porem não esta funcionando da maneira correta. O que pode está errado na minha implementacao? 


#include <Generic\ArrayList.mqh>

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart() {

   // minha classe 
   CPessoa *p;
    
   // arrayList com
   CArrayList<CPessoa> minhaLista = new CArrayList<CPessoa>();

   for(int i = 0; i < 5; i++) {

      //criacao do novo objecto CPessoa
      p = new CPessoa();
      
      //adiciona os valores
      p.nome = "Nome " + i;
      p.sobrenome = "Sobrenome " + i;
      p.idade = i * 2 + 1;

      //adiciona o objeto CPessoa ao array
      minhaLista.Add(p);
   }
}

class CPessoa {
 public:
   CPessoa(void) {};
   ~CPessoa(void) {};

   string nome;
   string sobrenome;
   int idade;
};
 
Nelson Lucas Amorim Teofilo Da Silva:

....

Tente fazer isso com um arrayObject, outra observação é, por questões de boas práticas não defina um atributo (variável) como public.

#include <Arrays\ArrayObj.mqh>
#include <Object.mqh>

CArrayObj array_list;
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   for(int i = 0; i < 5; i++)
     {
      //adiciona o objeto CPessoa ao array
      CPessoa *p=new CPessoa("Nome " + i,"Sobrenome " + i, i * 2 + 1);
      array_list.Add(p);
     }
     
   for(int i=0; i<array_list.Total(); i++)
     {
      CPessoa *p=array_list.At(i);
      delete p;
     }
   
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class CPessoa : public CObject
  {
private:
   string            nome;
   string            sobrenome;
   int               idade;
public:
                     CPessoa(string nome, string sobrenome, int idade);
                    ~CPessoa(void) {};


  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
CPessoa::CPessoa(string nome,string sobrenome,int idade)
  {
   CPessoa::nome=nome;
   CPessoa::sobrenome=sobrenome;
   CPessoa::idade=idade;
  }
//+------------------------------------------------------------------+
 
Jonathan Pereira:

Tente fazer isso com um arrayObject, outra observação é, por questões de boas práticas não defina um atributo (variável) como public.

Primeiramente agradeco pela ajuda; Irei testar e adaptar ao meu cenário. Com relacao as variaveis,  concordo com sua observacao, mas como esse era somente para fins de aprendizado, deixei tudo como public.

 
Nelson Lucas Amorim Teofilo Da Silva:

Primeiramente agradeco pela ajuda; Irei testar e adaptar ao meu cenário. Com relacao as variaveis,  concordo com sua observacao, mas como esse era somente para fins de aprendizado, deixei tudo como public.

Ah ok Nelson, é mais uma observação para as pessoas que não conhecem POO e que se baseiam em nossas respostas, inicialmente quando vi seu código imaginei que seu nível era mais avançado, e desconfio que vc é um JAVEIRO, rsrsrsrsrs...

Abraços.

 
Jonathan Pereira:

Ah ok Nelson, é mais uma observação para as pessoas que não conhecem POO e que se baseiam em nossas respostas, inicialmente quando vi seu código imaginei que seu nível era mais avançado, e desconfio que vc é um JAVEIRO, rsrsrsrsrs...

Abraços.

Jonathan Pereira ,

Funcionou perfeitamente, entretanto o modelo que vc indicou não é o mais adequando para a minha necessidade. Fiz algumas alterações no código e ficou da seguinte maneira: 


#include <Generic\ArrayList.mqh>




class CPerson {

public:

   string name;
   int age;

   CPerson(void) {};
   ~CPerson(void) {};

};


//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit() {


   //cria a lista generica
   CArrayList<CPerson*> list = new CArrayList<CPerson*>();

   CPerson *person;
   CPerson *personOutput;

   for(int i = 0; i < 20; i++) {

      //inicializa
      person = new CPerson();

      //atribui valores os atributos da classe
      person.name = "Fulano_" + i;
      person.age = i * i;

      // adiciona o objeto na lista
      list.Add(person);

   }


   //percorre todos os daos da lista
   for(int i = 0; i < list.Count(); i++) {

      //cria uma classe temporaria
      personOutput = new CPerson();

      // adiciona os dados da lista na
      list.TryGetValue(i,personOutput);

      // imprime os dados da lista
      PrintFormat("Name => %s, Age  => %d",
                  personOutput.name,
                  personOutput.age);

      //destroi o obj
      delete personOutput;
   }


//---
   return(INIT_SUCCEEDED);
}


Saída: 

saida

Não sei se é a forma mais correta, porem funcionou. Caso tiver dicas ou recomendações para esse modelo, estou aberto a ideias.

 
Nelson Lucas Amorim Teofilo Da Silva:

....

A titulo de curiosidade eu fui comparar e pelo menos pra mim não há diferença, ou não entendi o seu obejtivo.

Deixei a classe simples que nem no seu exemplo e o resultado é exatamente o mesmo, porem tem duas diferenças, uma positiva e outra negativa.

-Positiva: O arraylist se mostrou ligeiramente mais rápido, mas de uma forma muito sutil.

ArrayList

ArrayObj

-Negativo : fica objeto preso na memoria  como mostra a imagem abaixo. Num cenário com milhares de registros isso levaria a um consumo de memória exagerado. Tentei algumas formas e não obtive sucesso em remover, ainda estou analisando para entender se há a possibilidade de liberar a memoria.

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
#include <Generic\ArrayList.mqh>
#include <Arrays\ArrayObj.mqh>
#include <Object.mqh>
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class CPerson
  {

public:

   string            name;
   int               age;

                     CPerson(void) {};
                    ~CPerson(void) {};

  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class CPessoa : public CObject
  {

public:
                     CPessoa(void) {};
                    ~CPessoa(void) {};

   string            m_nome;
   int               m_idade;
  };

CArrayObj array_obj;

CArrayList<CPerson*> list;
CPerson *person;
CPerson *personOutput;
CPessoa *p;
ulong start=0,time=0;

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   Print("ArrayObj Inicio");
   start=GetMicrosecondCount();
   for(int i = 0; i < 20; i++)
     {
      //adiciona o objeto CPessoa ao array
      p=new CPessoa();
      p.m_nome  = "Fulano_" + i;
      p.m_idade = i * i;
      array_obj.Add(p);
     }

   for(int i=0; i<array_obj.Total(); i++)
     {
      p=array_obj.At(i);
      PrintFormat("Name => %s, Age  => %d",
                  p.m_nome,
                  p.m_idade);
      delete p;
     }

   time=GetMicrosecondCount()-start;
   Print("Time (MicroSecond): ",time);
   
   Print("ArrayObj fim");
   Print("ArrayList Inicio");
   start=0;

   start=GetMicrosecondCount();
   for(int i = 0; i < 20; i++)
     {
      //inicializa
      person = new CPerson();

      //atribui valores os atributos da classe
      person.name = "Fulano_" + i;
      person.age = i * i;

      // adiciona o objeto na lista
      list.Add(person);
     }

//percorre todos os daos da lista
   for(int i = 0; i < list.Count(); i++)
     {
      //cria uma classe temporaria
      personOutput = new CPerson();

      // adiciona os dados da lista na
      list.TryGetValue(i,personOutput);

      // imprime os dados da lista
      PrintFormat("Name => %s, Age  => %d",
                  personOutput.name,
                  personOutput.age);

      //destroi o obj
      delete personOutput;
     }
   time=GetMicrosecondCount()-start;
   Print("Time (MicroSecond): ",time);
   Print("ArrayList fim");
  }

Saida ArrayObj:


Saida ArrayList:


 
Qual função do * na codigo: 
CPessoa *p
  CArrayList<CPerson*> list = new CArrayList<CPerson*>();