List<Type> in MQL5

 

I have a background in C#, and wondering how I can get a list of type T in MQL5. 

For example, if I have the below class: 

class Person
{
public:
   Person();
   ~ Person();

private: 

};

In C#, I could easily get a list by using :

List<Person> myList = new List<Person>();

How can I achieve this in MQL5? I have tried the below, but I am getting an error. 

class PeopleManager
{
public:
   PeopleManager();
   ~PeopleManager();
   
   CList *People;
   
private:

};

void Main()
{
   PeopleManager pm = new PeopleManager();
   Person *p = new Person();

   pm.People.Add(p);            // error!!
}
 

Hi

class Person
{
public:
   Person();
   ~ Person();

private: 

};
class PeopleManager
{
public:
   PeopleManager(){for(int i=0;i<ArraySize(people);i++){delete(GetPointer(people[i]));}ArrayFree(people);}
   ~PeopleManager(){for(int i=0;i<ArraySize(people);i++){delete(GetPointer(people[i]));}ArrayFree(people);}
   
   person people[];
   
private:

};
 
//+------------------------------------------------------------------+
//|                                                        forum.mq5 |
//|                                     Copyright 2020, Lethan Corp. |
//|                           https://www.mql5.com/pt/users/14134597 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, Lethan Corp."
#property link      "https://www.mql5.com/pt/users/14134597"
#property version   "1.00"
//+------------------------------------------------------------------+
//| 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;
  };
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {

   CArrayObj array_obj;

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

   Print("ArrayObj Inicio");
   start=GetMicrosecondCount();
   for(int i = 0; i < 20; i++)
     {
     
      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++)
     {
   
      person = new CPerson();

      
      person.name = "Fulano_" + i;
      person.age = i * i;

      list.Add(person);
     }

   for(int i = 0; i < list.Count(); i++)
     {
      list.TryGetValue(i,personOutput);

      PrintFormat("Name => %s, Age  => %d",
                  personOutput.name,
                  personOutput.age);

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

  }
//+------------------------------------------------------------------+

Criar lista do tipo CArrayList<T> com os dados de minha classe - Geral - Fórum de negociação algorítmica MQL5

Criar lista do tipo CArrayList com os dados de minha classe
Criar lista do tipo CArrayList com os dados de minha classe
  • 2020.10.29
  • www.mql5.com
Estou tentando implementar uma lista CArrayList com alguns dados do tipo CPessoa porem não esta funcionando da maneira correta...
 
Lorentzos Roussos #:

Hi

Thank you - I forgot to mention the reason why I thought a List<Person> was required, and that is because I want to remove some Person classes as my program runs, and so to me List<Person> would have a dynamic size. Does your approach consider this? I see you used ArrayFree, which after reading the docs:

ArrayFree

It frees up a buffer of any dynamic array and sets the size of the zero dimension to 0.

Does this mean, for example, if I delete people[0] and people[1], and use ArrayFree() it will set people[2] to people[0] by releasing the memory?  

 

Thank you - let me take a look at implementing this! Did you find way to do a clean up and free memory?

 
You can add objects inherited from CObject to a List. 
 
Laszlo Tormasi #:
You can add objects inherited from CObject to a List. 

I tried that, but was getting an access error... I have implemented using  CArrayList as suggested above and that seems to work. Just haven't tested at scale yet. 

 
DeanDeV #:

I tried that, but was getting an access error... I have implemented using  CArrayList as suggested above and that seems to work. Just haven't tested at scale yet. 

#include <Arrays\List.mqh>

class Person : public CObject
{
public:
   Person(){};
   ~ Person(){};

private: 

};

class PeopleManager
{
public:
   PeopleManager(){};
   ~PeopleManager(){};
   
   CList People;
   
private:

};

void OnStart()
  {
//---

   PeopleManager pm;
   Person *p = new Person();

   pm.People.Add(p);            
}
 
Laszlo Tormasi #:

Ahhh I was using :

CList *People;

Which was probably causing the error, thanks! 

 
DeanDeV #:

Ahhh I was using :

Which was probably causing the error, thanks! 

Yes, you are right. 

CList *People;

Is an empty pointer.

In that case you need to create an instance: 

   PeopleManager()
        {
        People=new CList();
        };

   ~PeopleManager()
        {
        delete People;
        };
   
   CList *People;
 
DeanDeV #:

Thank you - I forgot to mention the reason why I thought a List<Person> was required, and that is because I want to remove some Person classes as my program runs, and so to me List<Person> would have a dynamic size. Does your approach consider this? I see you used ArrayFree, which after reading the docs:

ArrayFree

It frees up a buffer of any dynamic array and sets the size of the zero dimension to 0.

Does this mean, for example, if I delete people[0] and people[1], and use ArrayFree() it will set people[2] to people[0] by releasing the memory?  

Now it does 

class Person
{
public:
   long id;
   Person(){id=-1;}
   ~ Person(){id=-1;}
private: 

};
class PeopleManager
{
public:
   Person people[];
   
   PeopleManager(){reset();}
   ~PeopleManager(){reset();}
   
void reset(){
   for(int i=0;i<ArraySize(people);i++){delete(GetPointer(people[i]));}ArrayFree(people);
   }
int add_get_ix(){
   int ns=ArraySize(people)+1;
   ArrayResize(people,ns,0);
   return(ns-1);
   }
int add_get_ix(long new_id){
   int ix=add_get_ix();
   people[ix].id=new_id;
   return(ix);
   }
Person* add(long new_id){
   int ix=add_get_ix();
   people[ix].id=new_id;
   return(GetPointer(people[ix]));
   }   
int remove(int ix){
   if(ix>=0&&ix<ArraySize(people)){
   int ns=ArraySize(people)-1;
   people[ix]=people[ns];
   delete(GetPointer(people[ns]));
   if(ns==0){ArrayFree(people);}else{
   ArrayResize(people,ns,0);
   }
   }
   return(ArraySize(people));
   }
int find_ix(long with_id){
   for(int i=0;i<ArraySize(people);i++){
   if(people[i].id==with_id){
   return(i);
   }}
   return(-1);
   }
Person* find(long with_id){
   int ix=find_ix(with_id);
   if(ix>=0&&ix<ArraySize(people)){
   return(GetPointer(people[ix]));}
   return(NULL);
   }
int find_and_remove(long with_id){
   int ix=find_ix(with_id);
   return(remove(ix));
   }
private:

};
Reason: