Perguntas sobre OOP em MQL5 - página 16

 
Dmitry Fedoseev:

Abiblioteca padrão assume que os controles são criados em um formulário. Eles não devem funcionar de forma alguma, assim sem mais nem menos. Pelo menos, era assim que costumava ser.

Vou ter que experimentar as últimas versões da série GUI da Kajarski. A rapidez com que funciona para ele. E depois escreva novamente aos desenvolvedores para ajustar suas idéias.
 
Vasiliy Pushkaryov:
Terei que experimentar a última versão da série de artigos da Kajarsky sobre GUI. A rapidez com que funciona para ele. E depois, mais uma vez, escrever para os desenvolvedores para ajustar o cérebro de seus filhos.

todos andam no mesmo círculo! ))) - Foi a partir desta série de artigos sobre interfaces gráficas que comecei a estudar as capacidades do MQL .... - A experiência não foi boa, alguns dos exemplos nos artigos não são mais compilados, o autor mantém contato, mas o tamanho da biblioteca é muito grande, eu não comecei a usá-la, embora você possa ter sucesso nela.

imho - você estuda C# por uma semana - você tem muitos exemplos na web e o designer de formulários em VS é o mesmo que em Delphi (eu escrevi anteriormente em Delphi), ou usa SB de qualquer forma - pelo menos tem o suporte dos desenvolvedores

 
Igor Makanu:

todos andam no mesmo círculo! ))) - Foi a partir desta série de artigos sobre interfaces gráficas que comecei a estudar as capacidades do MQL .... - A experiência não foi boa, alguns dos exemplos nos artigos não são mais compilados, o autor mantém contato, mas o tamanho da biblioteca é muito grande, eu não comecei a usá-la, embora você possa ter sucesso nela.

imho, ou aprender C# por uma semana - você tem muitos exemplos na web e o designer de formulários em VS é o mesmo que em Delphi (em Delphi eu escrevi anteriormente), ou usar SB tudo o mesmo - pelo menos tem suporte dos desenvolvedores

Lamento saber que a biblioteca já está sendo embrulhada. Eu tentei há cerca de um ano atrás, gostei do visual do painel. Cheguei até a afinar para o MT4 e experimentei (por causa das diferenças na tela que também não compilava imediatamente), mas depois, devido à dificuldade de portar para minha tarefa, tomei SB. Pensei em voltar mais tarde para as GUIs.

Acho que não conseguiria dominar o C# em uma semana. Mas devo estabelecer uma meta, além disso, já existe apoio nativo para as bibliotecas .NET. Aqui você sugeriu como ele pode ser usado para sua tarefa específica.

 
Vladimir Simakov:

E, no segundo caso, você precisa

void  AddValue (T &value)  { Tptr  = value; mlist.Add(Tptr);       }

Não funcionou com sua versão por alguma razão, talvez eu tenha feito asneira de novo )) ,

Quero salvar os dados em uma lista sem indicações intermediárias, funciona desta forma e sem vazamentos de memória:

#property strict
#include <Arrays\List.mqh>
//+------------------------------------------------------------------+
template<typename T>class CDataBase
  {
private:
   CList            *mlist;
public:
   void CDataBase()           { mlist=new CList;                                    }
   void ~CDataBase(void)      { delete mlist;                                       }
   int ArraySize(void)        { return(mlist.Total());                              }
   T operator[](int index)    { return(mlist.GetNodeAtIndex(index));                }
   void  AddValue (T value)   { mlist.Add(value);                                   }
   void  Delete(int pos)      { mlist.Delete(pos);                                  }
   string TypeName()          { return(typename(T));                                }
  };

//+------------------------------------------------------------------+
class CData : public CObject
  {
public:
   int               x;
   double            y;
                     CData(){};
                     CData(int ival,double dval){x=ival;y=dval;}
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnStart()
  {
   CDataBase<CData*>*data=new CDataBase<CData*>;
   int i;
   for(i=0; i<5; i++) data.AddValue(new CData(i,i*2.0));
   Print("Тип БД : ", data.TypeName()," б чтение данных :");
   for(i=0; i<data.ArraySize(); i++) Print(i," : ",data[i].x," , ",data[i].y);
   Print("Удалил № 3");
   data.Delete(3);
   for(i=0; i<data.ArraySize(); i++) Print(i," : ",data[i].x," , ",data[i].y);
   delete data;
  }
//+------------------------------------------------------------------+

este é apenas o começo da minha idéia

Quero implementar em meu template a escrita e leitura em arquivo binário (embora eu pudesse fazer isso em um arquivo de texto, não importa). Não tenho idéia de como escrever CData em um arquivo usando um template de campo de classe - mas eu realmente quero fazer isso!

 
Igor Makanu:

Eu quero implementar em meu template a escrita e leitura em arquivo binário (embora seja possível escrever em arquivo texto - não importante), eu não sei como escrever campos de CData em arquivo usando o template - mas eu realmente quero! ;)

#property strict
#include <Arrays\List.mqh>
//+------------------------------------------------------------------+
struct FILE
{
  const int handle;
  
  FILE( const string FileName, const int Flags ) : handle(::FileOpen(FileName, Flags)) {}  
  ~FILE( void ) { if (this.handle != INVALID_HANDLE) ::FileClose(this.handle); }
};

template <typename T>
class CList2 : public CList
{
public:  
  virtual CObject  *CreateElement(void) { return(new T); }
};

template<typename T>class CDataBase
  {
private:
   CList2<T>            *mlist;
public:
   void CDataBase()           { mlist=new CList2<T>;                                    }
   void ~CDataBase(void)      { delete mlist;                                       }
   int ArraySize(void)        { return(mlist.Total());                              }
   T* operator[](int index)    { return(mlist.GetNodeAtIndex(index));                }
   void  AddValue (T* value)   { mlist.Add(value);                                   }
   void  Delete(int pos)      { mlist.Delete(pos);                                  }
   string TypeName()          { return(typename(T));                                }
  bool Save( const string FileName ) const { const FILE File(FileName, FILE_WRITE | FILE_BIN); return(this.mlist.Save(File.handle)); }
  bool Load( const string FileName ) { const FILE File(FileName, FILE_READ | FILE_BIN); return(this.mlist.Load(File.handle)); }

  };

//+------------------------------------------------------------------+
class CData : public CObject
  {
public:
   int               x;
   double            y;
                     CData(){};
                     CData(int ival,double dval){x=ival;y=dval;}
   virtual bool      Save( const int file_handle ) { return(::FileWriteInteger(file_handle, this.x) && ::FileWriteDouble(file_handle, this.y)); }
   virtual bool      Load( const int file_handle )
   {
     ::ResetLastError();
     
     this.x = ::FileReadInteger(file_handle);
     this.y = ::FileReadDouble(file_handle);
     
     return(!::GetLastError());
   }
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnStart()
  {
   CDataBase<CData>*data=new CDataBase<CData>;
   int i;
   for(i=0; i<5; i++) data.AddValue(new CData(i,i*2.0));
   Print("Тип БД : ", data.TypeName()," б чтение данных :");
   for(i=0; i<data.ArraySize(); i++) Print(i," : ",data[i].x," , ",data[i].y);
   
   data.Save("Data.bin");
   delete data;

   CDataBase<CData> data2;   
   data2.Load("Data.bin");
   Print("Тип БД : ", data2.TypeName()," б чтение данных :");
   for(i=0; i<data2.ArraySize(); i++) Print(i," : ",data2[i].x," , ",data2[i].y);
  }
//+------------------------------------------------------------------+

Eu nunca trabalhei com CList e CObject, mas as fontes são simples (a propósito, existe um método virtual Save without modificifier const por alguma razão), então funcionou de uma só vez.


SZY É mais fácil de escrever assim.

template<typename T>class CDataBase
  {
private:
   CList2<T>            mlist; // Объект, не указатель

Então você não precisará de construtor/destrutor. Faz sentido usar o new/delete onde ele é realmente útil. Caso contrário, você pode fazer o mesmo que com o FILE acima.

 
fxsaber:

Nunca funcionou com CList e CObject, mas o código fonte é simples, portanto, funcionou imediatamente.

Oh! você tem uma resposta tão rápida! - OBRIGADO! - Eu terei algo para fazer à noite.

Eu também fonte CList e CObject, leia, não vejo os problemas, mas os testes precisam conduzir

ZS: aqui em geral o que eu quero obter... uma espécie de lista universal:

1. em que estruturas de classe podem ser adicionadas imediatamente na criação (implementado - ver meus dados de exemplo. AddValue(novo CData(i,i*2.0)) - OK)

2. No qual você pode escrever e ler do arquivo "DB" (começou a escrever, até agora o construtor do modelo é

1. void CDataBase()           { mlist=new CList; m_file_handle=INVALID_HANDLE;         }
2. void CDataBase(int BaseID) { mlist=new CList;m_id=BaseID;m_file_handle=fileopen();  }

trabalhar sem escrever/leitura no arquivo #1 e #2 ler o banco de dados quando o CDataBase é criado a partir do disco e escrever no disco quando o destrutor é chamado

....

ZS:

qual é o objetivo de tudo isso? -Eu apenas escrevo EAs de acordo com um esquema padrão - um mágico e todas as manipulações com pedidos através da busca de um pedido com um mágico, se o TS não for "101 indicador" mas mais complicado, geralmente 2 mágicos são suficientes, mas se o TS estiver monitorando 80 pedidos pendentes (10 grades de pedidos, as grades são reabertas e ... Para ser honesto, é absurdo, mas eu o encontrei pela segunda vez), então eu começo a usar vários truques - liderando 80 pedidos em 80 mágicos gerados )))) - Eu me safei, mas não gosto de tudo isso

Eu gostaria de finalmente criar um pequeno banco de dados onde eu seria capaz de escrever dados sobre pedidos (tudo mais) e, mais importante, não prestar atenção ao banco de dados em si - acesso aelementos de array, leitura e escrita em um arquivo quando a EA é aberta ou fechada

e assim por diante ))))


fxsaber:

SZZ É mais fácil de escrever

Então você não precisa de um construtor/destrutor. O new/delete deve ser usado onde for realmente útil. Quanto ao resto, você pode fazer o que fez com o FILE acima.

Obrigado, mas ainda preciso pensar sobre isso ... ou melhor, quero fazê-lo de tal forma que não tenha que pensar sobre isso mais tarde)))) - quando OnInit() cria o banco de dados, ele lê o arquivo e DeInit() mata o banco de dados, salva o arquivo e se você perdeu a exclusão em DeInit(), o terminal vai escrever algo sobre isso no diário... Na minha opinião, exclui erros ao trabalhar com o banco de dados. em geral, se eu fizer isso, verei como é conveniente

 
fxsaber:
virtual bool      Load( const int file_handle )
   {
     ::ResetLastError();
     

se você não se importa, por que usar " :: "https://www.mql5.com/ru/docs/basis/operations/other

 
Igor Makanu:

se você não se importa, por que usamos " :: " aqui?

Caso contrário, tenho que verificar se as classes-mãe não têm um método com o mesmo nome. E mesmo que não haja, se alguém o acrescentar, o código ainda funcionará.

Pela mesma razão, eu sempre uso isto para a clareza e legibilidade.


ZZY Mas em algumas situações raras :: e isto retira flexibilidade. Há sutilezas semelhantes sobre quando é melhor escrever o corpo do método dentro da classe e quando é melhor escrevê-lo fora. Lembro-me de encontrar tudo isso, mas não vou dar exemplos.

 
fxsaber:

Caso contrário, tenho que verificar se as classes-mãe não têm um método com o mesmo nome. E mesmo que não haja, se alguém o acrescentar, o código ainda funcionará.

Pela mesma razão, eu sempre uso isto para clareza e legibilidade.

Sim, é realmente prático e evita bugs, vou levar isso em consideração

Obrigado!

 
Igor Makanu:

4. Se a bandeira de gravação do arquivo m_fsave estiver ativa, então cada vez que chamamos o método AddValue() - adicionamos mais dados ao arquivo

Veja o formato de registro da CList. Você está ignorando isso.

Razão: