Preguntas sobre POO en MQL5 - página 46

 
Igor Makanu:

eso es exactamente lo que me alejé, y eso es lo que hice al principio

con este enfoque - heredar de una clase base, "donde está todo" - todo funciona, pero hasta que queremos intentar hacer varios campos de clase, y luego queremos añadir más campos en cada clase de campo, y clavarlo todo con una matriz dinámica de clases

y entonces obtendremos que no podemos implementar el método Save(int hndl) propiamente dicho en una clase base - este método será en realidad una interfaz, que, como se ha comentado anteriormente, no será necesaria en absoluto - se puede escribir sin interfaces

suelo maximizar mis esfuerzos en la flexibilidad del código - mínimo alboroto - el resultado es un nuevo problema resuelto, que mi terminología sea perdonada)))


el problema será que, al implementar el guardado en un archivo, es necesarioelaborar el encabezado del archivo, que debe describir la cantidad total de los diferentes tipos de entradas y luego es necesario no perder la lógica / el orden de guardado de los datos, para poder leer todo correctamente.... y el final será si cambias aunque sea un campo de una clase

En mi opinión, la laboriosidad de una herencia tan "fácil" a partir de una clase base - se reduce al desarrollo y mantenimiento de una pequeña base de datos, a la supervisión constante de los cambios en cualquier clase

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

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

Algo como esto))))

 
Vladimir Simakov:

Algo como esto))))

Entiendo todo esto, pero al viejo dicho "MQL no es C", sólo se puede añadir que no tiene sentido confiar en un código bien estructurado por tareas - las tareas MQL son siempre altamente especializadas y la reutilización de un código grande no suele ser efectiva.

HH: en mi opinión, el objetivo principal del código MQL es ser lo más rápido posible, para ser utilizado en el probador o para ejecutar el código dentro de un tic - sin perder tics, todo está claro, pero hay algunas restricciones - no se puede ignorar las interrupciones de la conexión y el reinicio del PC / terminal, y se trata de encontrar el óptimo, no sóloun códigobonito y estructurado

 
Igor Makanu:

2. ¿existe un hack para describir operator= , y utilizar el operador de copia nativo en él? .... es decir, alguna forma de llamar a : :=

hay una manera, y como siempre la solución es sencilla:

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 la matriz A, entonces C

primero asignamos una nueva matriz B = A y desinicializamos , luego B = C y 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

el punto - necesitas envolver la estructura en la estructura y de nuevo en la estructura.... disculpe mi término técnico ))))


SZY: la solución es buena, deberíamos sustituir los métodos RowCount() y ColCount() por campos de estructura RowCount y ColCount(), para hacer menos llamadas... Pero en general, funciona como yo quería

 
¿Hablas en serio?
 
Алексей Тарабанов:
¿Hablas en serio?

Qué más da, el hombre lleva resolviendo este problema desde 2012, no le molestes, él sabe más.

 
Sergey Dzyublik:

Qué más da, el hombre lleva resolviendo este problema desde 2012, no le molestes, él sabe más.

Estás pensando en plano.

la tarea consiste en conocer las capacidades técnicas del lenguaje MQL, para que dicho ejemplohttps://docs.microsoft.com/en-us/archive/msdn-magazine/2018/april/test-run-understanding-lstm-cells-using-csharp

puede ser portado "directamente" - esta tarea ha sido resuelta ahora, portando todas las funciones del ejemplo uno a uno con una suposición: float[][] result --> SMatrix result

 
Igor Makanu:

hay una manera, y como siempre la solución es sencilla:

inicializar la matriz A, entonces C

primero asignar una nueva matriz B = A y desinicializar , luego B = C y desinicializar


SZY: la solución es buena, hay que sustituir los métodos RowCount() y ColCount() por campos de estructura RowCount y ColCount() para hacer menos llamadas ... Pero en general, todo funciona como quería.

Desafortunadamente, no todo es tan feliz como nos hubiera gustado. En MQL, hay un error de larga data con la copia de matrices por el operador de copia por defecto. Sólo ArrayCopy de elementos de una matriz a otra tiene lugar. El tamaño del array resultante no está sincronizado con el origen (no está truncado). Esto significa que, si A(10) y B(20) estaban presentes, después de B=A se obtendrá también B(20), es decir, la mitad de los elementos serán reemplazados por elementos de A, el resto permanecerá igual. Esto, por supuesto, no es en absoluto lo que se espera del operador=. Por eso tendremos que escribir nuestro propio operador para arrays.

Debo confesar que creía que este fallo ya estaba solucionado. Pero lo he comprobado y sigue ahí.

 
Alexey Navoykov:

Desgraciadamente, no todo es tan feliz como nos gustaría. MQL tiene un error de larga duración con la copia de arrays utilizando el operador de copia por defecto. Sólo se produce el ArrayCopy de elementos de un array a otro. El tamaño del array resultante no está sincronizado con el origen (no está truncado). Esto significa que, si A(10) y B(20) estaban presentes, después de B=A se obtendrá también B(20), es decir, la mitad de los elementos serán reemplazados por elementos de A, el resto permanecerá igual. Esto, por supuesto, no es en absoluto lo que se espera del operador=. Por eso tendremos que escribir nuestro propio operador para arrays.

Debo confesar que creía que este fallo ya estaba solucionado. Pero lo he comprobado y sigue ahí.

El bicho fue retirado recientemente:

Foro sobre comercio, sistemas de comercio automatizados y pruebas de estrategia

Preguntas sobre POO en MQL5

Sergey Dzyublik, 2020.04.18 17:48

Entonces, según su terminología, llamar al operador de asignación por defecto puede dar "un tipo de datos incompleto".
Error de la versión 2019.05.03 nunca corregido:https://www.mql5.com/ru/forum/1111/page2451#comment_11556395


Se supone que la línea dada debe evitar el error:

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:

La línea dada debería evitar el error:

Oh, sí, no me di cuenta al principio... Pero entonces podrías haber escrito ArrayCopy de inmediato. ¿Por qué necesitamos entonces esta junta SMATRIX?

 
Alexey Navoykov:

Oh, sí, no me di cuenta al principio... Pero entonces podrías haber escrito ArrayCopy de inmediato. ¿Por qué necesitamos esta almohadilla SMATRIX en absoluto?

МТ los desarrolladores siempre escriben que el uso de los mecanismos incorporados en el compilador será más rápido incluso que llamar a las funciones estándar

Si tienes tiempo e interés, comprueba la velocidad de mi versión y la tuya con ArrayCopy

Comprobaré la velocidad un poco más tarde, estoy en medio de una clase

Razón de la queja: