Perguntas sobre OOP em MQL5 - página 46

 
Igor Makanu:

foi exatamente disso que me afastei, e foi o que fiz no início

com esta abordagem - herdar de uma classe base, "onde tudo está" - tudo funciona, mas até que queremos tentar fazer vários campos de classe, e então queremos adicionar mais campos em cada classe de campo, e pregar tudo isso com uma matriz dinâmica de classes

e então conseguiremos que não possamos implementar o próprio método Save(int hndl) em uma classe base - este método será na verdade uma interface, que, como discutido acima, não será de forma alguma necessária - você pode escrevê-lo sem interfaces

normalmente maximizo meus esforços em flexibilidade de código - mínimo alarido - resultado é um novo problema resolvido, que minha terminologia possa ser perdoada))))


o problema será, ao implementar o salvamento em arquivo, você precisatrabalhar o cabeçalho do arquivo, que deve descrever a quantidade total de diferentes tipos de entradas e então você não precisa perder a lógica / ordem de salvamento de dados, a fim de ler tudo corretamente.... e o final será se você mudar até mesmo um campo em uma classe

imho, a laboriosidade dessa herança "fácil" de uma classe base - se resume ao desenvolvimento e manutenção de um pequeno banco de dados, monitoramento constante das mudanças em qualquer classe

public:
 void CBase::Save(...){
    SaveHeard(...);
    _Save(...)}
virtual void SaveHeard(...){...}

protected:
   void _Save(...){
       CBase::_Save(...);
       ...}

Algo como isto))))

 
Vladimir Simakov:

Algo como isto))))

Eu entendo tudo isso, mas ao velho ditado "MQL não é C", você só pode acrescentar que não faz sentido confiar em um código bem estruturado por tarefas - as tarefas MQL são sempre altamente especializadas e a reutilização de códigos grandes muitas vezes não é eficaz.

HH: imho o objetivo principal do código MQL é ser o mais rápido possível, ser usado no testador ou executar o código dentro de um tick - sem perder ticks, está tudo claro, mas há algumas restrições - você não pode ignorar a situação com quebras de conexão e reinicialização do PC / terminal, e tudo se resume a encontrar o código ideal, não apenasum códigoagradável e estruturado

 
Igor Makanu:

2. Existe um hack para descrever operator= , e usar o operador de cópia nativo nele? .... ou seja, alguma forma de chamar : :=

há uma maneira, e como de costume a solução é simples:

struct SMatrix
{
   struct SMATRIX{
   SMATRIX(){}
   struct SRow{int COL[];};
   SRow ROW[];
   };
   SMATRIX MATRIX;
   SMatrix(){}
   SMatrix(const int rows,const int cols){ this.Resize(rows,cols); }
   void Resize(const int rows,const int cols){ ArrayResize(this.MATRIX.ROW,rows); for(int i=0;i<rows; i++){ ArrayResize(this.MATRIX.ROW[i].COL,cols); }}
   void Free() { for(int i=0;i<ArraySize(this.MATRIX.ROW[i].COL); i++){ ArrayFree(this.MATRIX.ROW[i].COL); } ArrayFree(this.MATRIX.ROW);}
   int RowCount()const { return(ArraySize(this.MATRIX.ROW)); }
   int ColCount()const { if(this.RowCount()>0) return(ArraySize(this.MATRIX.ROW[0].COL)); else return(0); }
   void operator=(const SMatrix &v) { this.Resize(v.RowCount(),v.ColCount()); this.MATRIX = v.MATRIX;}

};

//+------------------------------------------------------------------+
void OnStart()
{
   SMatrix A(2, 5);
   int count = 0;
   for(int i = 0; i < A.RowCount(); i++)
      for(int j = 0; j < A.ColCount(); j++)
         A.MATRIX.ROW[i].COL[j] = count++;
   
   SMatrix C(5, 2);
   count = 100;
   for(int i = 0; i < C.RowCount(); i++)
      for(int j = 0; j < C.ColCount(); j++)
         C.MATRIX.ROW[i].COL[j] = count++;

   
   SMatrix B = A;
   for(int i = 0; i < B.RowCount(); i++)
      ArrayPrint(B.MATRIX.ROW[i].COL);
   
   B = C;
   for(int i = 0; i < B.RowCount(); i++)
      ArrayPrint(B.MATRIX.ROW[i].COL);
   
}

inicializamos a matriz A, depois a C

primeiro atribuímos uma nova matriz B = A e a desinicializamos, depois B = C e a desinicializamos

2020.04.21 00:35:50.559 tst (EURUSD,H1) 0 1 2 3 4

2020.04.21 00:35:50.559 tst (EURUSD,H1) 5 6 7 8 9

2020.04.21 00:35:50.560 tst (EURUSD,H1) 100 101

2020.04.21 00:35:50.560 tst (EURUSD,H1) 102 103

2020.04.21 00:35:50.560 tst (EURUSD,H1) 104 105

2020.04.21 00:35:50.560 tst (EURUSD,H1) 106 107

2020.04.21 00:35:50.560 tst (EURUSD,H1) 108 109

o ponto - você precisa envolver a estrutura na estrutura e novamente na estrutura.... desculpe meu termo técnico ))))


SZY: a solução é boa, devemos substituir os métodos RowCount() e ColCount() pelos campos de estrutura RowCount e ColCount(), para fazer menos chamadas... Mas no geral, funciona como eu queria que funcionasse

 
Você está falando sério?
 
Алексей Тарабанов:
Você está falando sério?

Qual é o problema, o homem tem resolvido este problema desde 2012, não o incomode, ele é que sabe.

 
Sergey Dzyublik:

Qual é o problema, o homem tem resolvido este problema desde 2012, não o incomode, ele é que sabe.

Você está pensando bem.

a tarefa é conhecer as capacidades técnicas da linguagem MQL, para que tal exemplo sejahttps://docs.microsoft.com/en-us/archive/msdn-magazine/2018/april/test-run-understanding-lstm-cells-using-csharp

pode ser portado "diretamente" - esta tarefa foi resolvida agora, portando todas as funções do exemplo um-para-um com uma suposição: float[][] resultado --> resultado SMatrix

 
Igor Makanu:

há uma maneira, e como de costume a solução é simples:

inicializar a matriz A, depois a C

primeiro atribuir uma nova matriz B = A e desinicializar, depois B = C e desinicializar


HH: a solução é boa, precisamos substituir os métodos RowCount() e ColCount() pelos campos de estrutura RowCount e ColCount() para fazer menos chamadas ... Mas, no geral, tudo funciona como eu queria.

Infelizmente, nem tudo é tão feliz quanto gostaríamos. Na MQL, existe um bug de longa data com a cópia de array pelo operador de cópia padrão. É apenas o ArrayCopy de elementos de um array para outro que ocorre. O tamanho da matriz resultante não está sincronizado com a fonte (não está truncado). Isso significa que, se A(10) e B(20) forem utilizados, depois de B=A você receberá B(20) também, ou seja, metade dos elementos serão substituídos por itens de A, o resto permanecerá o mesmo. Isto, é claro, não é de todo o que se espera do operador. É por isso que teremos que escrever nosso próprio operador para as arrays.

Devo confessar que eu pensava que este bug já tinha sido corrigido. Mas eu verifiquei e ele ainda está lá.

 
Alexey Navoykov:

Infelizmente, nem tudo é tão feliz quanto gostaríamos que fosse. A MQL tem um bug de longa data com a cópia de array usando o operador de cópia padrão. Apenas o ArrayCopy de elementos de um array para outro ocorre. O tamanho da matriz resultante não está sincronizado com a fonte (não está truncado). Isso significa que, se A(10) e B(20) forem utilizados, depois de B=A você receberá B(20) também, ou seja, metade dos elementos serão substituídos por itens de A, o resto permanecerá o mesmo. Isto, é claro, não é de todo o que se espera do operador. É por isso que teremos que escrever nosso próprio operador para as arrays.

Devo confessar que eu pensava que este bug já tinha sido corrigido. Mas eu verifiquei e ele ainda está lá.

O bug foi lembrado recentemente:

Fórum sobre comércio, sistemas automatizados de comércio e testes estratégicos

Perguntas OOP em MQL5

Sergey Dzyublik, 2020.04.18 17:48

Então, de acordo com sua terminologia, chamar o operador de atribuição padrão pode dar "tipo de dados incompletos".
Bug de 2019.05.03 nunca consertado:https://www.mql5.com/ru/forum/1111/page2451#comment_11556395


A linha dada é suposta contornar o bug:

struct SMatrix
{
   struct SMATRIX{
   SMATRIX(){}
   struct SRow{int COL[];};
   SRow ROW[];
   };
   SMATRIX MATRIX;
   SMatrix(){}
   SMatrix(const int rows,const int cols){ this.Resize(rows,cols); }
   void Resize(const int rows,const int cols){ ArrayResize(this.MATRIX.ROW,rows); for(int i=0;i<rows; i++){ ArrayResize(this.MATRIX.ROW[i].COL,cols); }}
   void Free() { for(int i=0;i<ArraySize(this.MATRIX.ROW[i].COL); i++){ ArrayFree(this.MATRIX.ROW[i].COL); } ArrayFree(this.MATRIX.ROW);}
   int RowCount()const { return(ArraySize(this.MATRIX.ROW)); }
   int ColCount()const { if(this.RowCount()>0) return(ArraySize(this.MATRIX.ROW[0].COL)); else return(0); }
   void operator=(const SMatrix &v) { this.Resize(v.RowCount(),v.ColCount()); this.MATRIX = v.MATRIX;}

};
 
Sergey Dzyublik:

A linha dada deve contornar o bug:

Ah, sim, eu não notei no início... Mas depois você poderia ter escrito ArrayCopy imediatamente. Por que precisamos então desta junta SMATRIX?

 
Alexey Navoykov:

Ah, sim, eu não notei no início... Mas depois você poderia ter escrito ArrayCopy imediatamente. Por que precisamos mesmo desta almofada SMATRIX?...

МТ os desenvolvedores sempre escrevem que usar mecanismos de compilação embutidos será mais rápido até mesmo do que chamar funções padrão

Se você tiver tempo e interesse, verifique a velocidade da minha versão e a sua com o ArrayCopy

Vou verificar a velocidade um pouco mais tarde, estou no meio de uma lição

Razão: