Preguntas sobre POO en MQL5 - página 35

 
Roman:

Si el objeto ha completado su tarea, ¿por qué mantenerlo en la memoria?
¿No habrá una fuga de memoria?

Lo hará, especialmente si no se borra ni siquiera en OnDeinit.
No es necesario que lo almacene en la memoria, si realmente ya no lo necesita. Pero lo más frecuente es que un objeto sea creado y utilizado en una iteración... Y luego en la segunda iteración... Y así sucesivamente. Y entonces, bajo ciertas condiciones, se crea otro objeto de la misma clase, y ya se trabaja con dos o más objetos de esta clase, cada uno de los cuales es necesario a lo largo de la vida del EA.

 
BlackTomcat:

Se producirá, sobre todo si no se borra ni siquiera en OnDeinit.
No es necesario que lo almacene en la memoria, si realmente ya no lo necesita. Pero lo más frecuente es que un objeto sea creado y utilizado en una iteración... Y luego en la segunda iteración... Y así sucesivamente. Y entonces, bajo ciertas condiciones, se crea otro objeto de la misma clase, y ya se trabaja con dos o más objetos de esta clase, cada uno de los cuales es necesario a lo largo de la vida del EA.

¿Así que quieres decir que una fuga de memoria controlada es mejor que recrear objetos?
Es decir, ahorrar tiempo, a cambio de demonios controlados?
Es peligroso no perderlos después.

 

escribió utilizando la plantillahttps://www.mql5.com/ru/forum/85652/page24#comment_13054686 del experto

una plantilla bastante flexible, permite añadir diferentes "pluses" en "2 clics" y el código resulta legible y lógico, pero... Volví a algún paradigma discutido de que una buena clase, bueno, no debería tener métodos estáticos

Suena bien en teoría, pero en la práctica... No en mi opinión, al menos para los problemas de MQL, imho.

De acuerdo con la plantilla, la clase EA fue escrita y un método público se inicia en OnTick(). Pero durante la inicialización del EA, quiero comprobar si hay órdenes abiertas e interceptarlas:

1. escribir una función en el OnTick() que si encuentra una orden abierta a través del asistente, crea un objeto EA; si no se encuentra ninguna orden, el objeto EA se inicializa según la lógica básica - el objeto EA se crea sólo en tiempo de negociación e implementa la lógica del TS en el futuro

2. Escriba una clase estática en EA, que implemente los puntos 1


Esencialmente los puntos 1 y 2 son los mismos, la diferencia es que en el paso 1, añado una función que tendría sentido sólo durante la inicialización del EA (la primera ejecución), pero imho, sobrecarga el código - ¡una función será llamada una vez para toda la ejecución del programa!

si hace un método estático ( pp.2 ), entonces será lógico y legible - el método es necesario sólo para la inicialización y define el momento, cuando el objeto EA debe ser creado - debe enviar a este método sólo un número mágico.


A mi entender prohibir el uso de métodos estáticos cuando es conveniente... por decirlo suavemente, mal.

 
Igor Makanu:

Losmétodos estáticos se diferencian de las funciones sólo en su ámbito de aplicación.


Esta práctica es peligrosa

input int inInput = 0;

const bool Init = EventSetTimer(1);

void OnTimer()
{
  static int Input = inInput;
  
  Print(Input);
}


Si cambia la entrada mientras el EA está en marcha, la Entrada no cambiará.

En consecuencia, está cargado de

input long inMagic = 0;

void OnTick()
{
  static ORDER Orders[]; // Список ордеров по мэджику или что-то подобное, зависящая от входных.
}
 
fxsaber:

Si cambias la entrada mientras el EA está funcionando, la entrada no cambiará.

Soy consciente de ello, y en mi TS no se pueden cambiar los parámetros de entrada mientras el EA está trabajando, el tiempo de ejecución está separado de la lógica del TS

Mi pregunta es puramente teórica, no quiero sobrecargar el código, así que estoy buscando la posibilidad de restaurar el TS después de estrellarse en algún lugar, hasta ahora lo veo así:

input int EAMagicNumber = 12345;
class CEA
{
public:
   static bool       NeedRecovery(int magic_)            {   return(true);    }
   bool              Recovery(int magic_,int inputparam) {   return(true);    }
                     CEA()                               {                    }
                     CEA(int inputparam)                 {                    }
                    ~CEA()                               {                    }
};

CEA *ea;

void OnStart()
{
   if(CheckPointer(ea)==POINTER_INVALID)
   {
      if(CEA::NeedRecovery(EAMagicNumber))   //если нашли открытые ордера с магиком
      {
         ea = new CEA();         // создали объект
         ea.Recovery(EAMagicNumber,11111);   // запустили восстановление ТС
      }else ea = new CEA(2222222);           //обычный запуск
   }
 
Igor Makanu

Tiene más sentido meter esta lógica en el constructor.

 
fxsaber:

Losmétodos estáticos se diferencian de las funciones sólo en su ámbito de aplicación.

Incorrecto. También tienen acceso a los miembros y métodos no públicos de la clase.
 
TheXpert:
incorrecto. también el acceso a los miembros y métodos no públicos de la clase.

Aquí hay un malentendido terminológico. El "área de visibilidad" no se refiere sólo a quién ve el método. Pero también lo que él mismo ve.

 
fxsaber:

Aquí hay un malentendido terminológico.

Después de todo, la visibilidad y el acceso son conceptos diferentes y es mejor no mezclarlos
 
fxsaber:

Tiene más sentido poner esta lógica en el constructor.

¡Sí, esa es una solución mejor! Así que hay un método menos

Así es como debe ser:

input int EAMagicNumber = 12345;
class CEA
{
public:
   static bool       NeedRecovery(int magic_)            {   return(true);    }  //тут проверки
                     CEA(int magic_)                     {                    }  //это обычный запуск если все ОК
                     CEA(int magic_, int recoveryparam)  {                    }  //тут аварийное восстановление
                    ~CEA()                               {                    } };

CEA *ea;

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnStart()
{  if(CheckPointer(ea)==POINTER_INVALID)
   {  if(CEA::NeedRecovery(EAMagicNumber))   //если нашли откртые ордера с магиком
      {  
         ea = new CEA(EAMagicNumber,11111);  // запустили востановление ТС
      }
      else ea = new CEA(EAMagicNumber);      //обычный запуск
   } 
}
TheXpert:
después de todo, la visibilidad y el acceso son conceptos diferentes y es mejor no mezclarlos
por eso tengo una duda, donde pondría una forma de detectar que la última ejecución se colgó, ahora mi estructura de código es compacta, todo sigue claramente el patrón que mostré arriba