Preguntas sobre POO en MQL5 - página 39

 

Ahora no es extraño por qué no hay suficiente Volchanskiy aquí, tipo duro Insider vista previa o lo que sea que utiliza))


He descargado win 10home desde el sitio off hace 3 meses, ni siquiera tuvo tiempo para configurar los ajustes básicos, el icono de opciones de inicio no se abre, sí ***********

 
Koldun Zloy:

He aquí un ejemplo:

Traté de aplicar completamente su ejemplo a mi tarea, pero de nuevo el mismo rastrillo - quiero terminar con la bandera "registro requerido" al crear un nuevo descendiente de una clase base:

//+------------------------------------------------------------------+
class CStrategy
{
private:
   int f_save_required;
protected:
   int set;
   void              SaveRequiredFlags (const bool flag)                      { f_save_required++;  }
   int               SaveRequiredFlags (void) const                           { return(f_save_required); }
public:
                     CStrategy():f_save_required(0)                           {  Print(__FUNCSIG__,"save = ",f_save_required);  }
                     CStrategy(int setting):set(setting),f_save_required(0)   {  Print(__FUNCSIG__,"save = ",f_save_required);  }
                    ~CStrategy(){}

};
//+------------------------------------------------------------------+
class A: public CStrategy
{
public:
   void              SaveRequired (void)                                      { SaveRequiredFlags(true);                         }
   int               getSaveRequired (void) const                             { return(SaveRequiredFlags());                     }
                     A(int st_setting) : CStrategy(st_setting){}
                    ~A(){}
};
//+------------------------------------------------------------------+
class B: public CStrategy
{
public:
   void              SaveRequired(void)                                       { SaveRequiredFlags(true);                         }
   int               getSaveRequired (void) const                             { return(SaveRequiredFlags());                     }
                     B(int st_setting) : CStrategy(st_setting){}
                    ~B(){}
};
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   A *a = new A(1);
   B *b = new B(2);
   a.SaveRequired();
   a.SaveRequired();
   a.SaveRequired();
   a.SaveRequired();
   b.SaveRequired();
   Print(a.getSaveRequired());
   Print(b.getSaveRequired());
//---
   return(INIT_SUCCEEDED);
  }

2019.09.14 16:07:26.856 Builder_v1.00 (EURUSD,H1) CStrategy::CStrategy(int)save = 0

2019.09.14 16:07:26.856 Builder_v1.00 (EURUSD,H1) CStrategy::CStrategy(int)save = 0

2019.09.14 16:07:26.856 Builder_v1.00 (EURUSD,H1) 4

2019.09.14 16:07:26.856 Builder_v1.00 (EURUSD,H1) 1

por ahora todo lo que ha funcionado:

1. no declarar las interfaces no era un problema en absoluto

2. Generé un montón de setters y getters pero no pude alejarme de las variables estáticas


He intentado reescribir el código de nuevo:

//+------------------------------------------------------------------+
class CStrategy
{
private:
   int f_save_required;
protected:
   int set;
   void              SaveRequiredFlags (const bool flag)                      { f_save_required++;  }
   int               SaveRequiredFlags (void) const                           { return(f_save_required); }
public:
virtual  void        SaveRequired (void)                                      { SaveRequiredFlags(true);                         }
virtual  int         getSaveRequired (void) const                             { return(SaveRequiredFlags());                     }
                     CStrategy():f_save_required(0)                           {  Print(__FUNCSIG__,"save = ",f_save_required);  }
                     CStrategy(int setting):set(setting),f_save_required(0)   {  Print(__FUNCSIG__,"save = ",f_save_required);  }
                    ~CStrategy(){}

};
//+------------------------------------------------------------------+
class A: public CStrategy
{
public:
                     A(int st_setting) : CStrategy(st_setting){}
                    ~A(){}
};
//+------------------------------------------------------------------+
class B: public CStrategy
{
public:
                     B(int st_setting) : CStrategy(st_setting){}
                    ~B(){}
};
//+------------------------------------------------------------------+



//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   CStrategy *a = new A(1);
   CStrategy *b = new B(2);
   
   a.SaveRequired();
   a.SaveRequired();
   a.SaveRequired();
   a.SaveRequired();
   b.SaveRequired();
   Print(a.getSaveRequired());
   Print(b.getSaveRequired());
//---
   return(INIT_SUCCEEDED);
  }

el resultado es exactamente el mismo que en la primera versión, lo único es alejarse de las interfaces

 
¿Cuál es el objetivo, qué se gana?
 
Dmitry Fedoseev:
¿Cuál es el objetivo, qué quieres conseguir?

todo funciona, pero el objetivo es adquirir conocimientos ))))

cómo lo hice:

- hay una clase base en la que se realizan todos los cálculos y almacena las configuraciones de TC, de ella heredamos descendientes que funcionan por su TC

- Creo que es razonable guardar el archivo en un archivo pasando el handle del archivo abierto a todos los descendientes; en este caso, el método save() aparece de nuevo en la clase base

- el guardado debe realizarse cuando se produce un evento/bandera - no se sabe qué descendiente lo inicia y cuándo, pero es más rápido guardar docenas de estructuras en un nuevo archivo que averiguarlo

- ¿por qué no hacer una clase y una matriz de ajustes? - Tengo que declarar uno o dos métodos como virtuales y añadirlos a cada TS.

- el problema: estoy tratando de alejarme de las variables estáticas con la esperanza de que haya un truco jedi de POO que no conozco





SZY: los modificadores de const son una buena cosa, no me arrepiento del tiempo invertido - útil, ¡gracias de nuevo por la discusión!

 

Si tienes que escribir los datos de todos los objetos de esta clase en un archivo, que se abre una vez, entonces no puedes hacerlo sin una variable estática. ¿Y por qué deshacerse de ella, si es la que mejor se adapta a la tarea? Por supuesto, también puedes declarar una variable global.

¿Y si cada objeto abriera, escribiera y cerrara un archivo? Entonces bastaría con tener un nombre de archivo en cada objeto... Pero también en este caso es mejor utilizar una variable estática, porque el valor de la variable es siempre el mismo en todas partes.

O no entiendo nada)

 
Dmitry Fedoseev:

Si tienes que escribir los datos de todos los objetos de esta clase en un archivo, que se abre una vez, entonces no puedes hacerlo sin una variable estática. ¿Y por qué deshacerse de ella, si es la que mejor se adapta a la tarea? Por supuesto, también puedes declarar una variable global.

¿Y si cada objeto abriera, escribiera y cerrara un archivo? Entonces bastaría con tener un nombre de archivo en cada objeto... Pero también en este caso es mejor utilizar una variable estática, porque el valor de la variable es siempre el mismo en todas partes.

O tal vez me equivoque)

En el archivo, que se abre una vez, escribimos los datos en él e inmediatamente se cierra, para no perder datos si el terminal se cuelga, grabando desde una vez en un minuto hasta una vez por hora - no tiene sentido mantener el archivo abierto durante tanto tiempo

hagámoslo en código, así es como es ahora:

// это один файл, его не трогаю, тут только конструктор и 3 метода из интерфейсов, чтобы дать стратегиям тик, чтобы закрыть их и вот чтобы записать все ТС в файл

//____________________________________________________________________
void EA::OnTick(double &profit[])
{
      for(int i = 0; i < StrategyCount; i++) profit[i] = Strategy[i].Strategy();  // запустили зоопарк стратегий и тут нам интересно дать им волю и узнать их профит, если ТС завершилась       
                                                                                  // она самостоятельно запустит "пустую стратегию", но профит будет возвращать первоначальный
      if(CStrategy::GetSaveRequired()) Save();                                    // вот тут узнаем состояние флага требуется ли запись состояния любой из ТС
}
//____________________________________________________________________
//это структура которая умеет открыть и записать файл, пример от fxsaber
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);  Print(__FUNCTION__);} 
};

//____________________________________________________________________
// метод для записи в файл состояния всех ТС, но проще записать все ТС один раз в файл, чем искать одну ТС..... в общем считаем, что скорость доступа к диску намного меньше чем работа с памятью
// используем структуру FILE - ну это просто удобно, объявили и забыли, она сама закроет файл когда уйдет из области видимости
void  EA::Save(void)
{  FILE f(DEF_PREFIX_FILE_NAME + IntegerToString(m_magic)+".bin",FILE_WRITE|FILE_BIN);
   for(int i = 0; i < StrategyCount; i++)
      Strategy[i].SaveSelfStatus(f.handle); 

}





// это основной файл (инклудник) в котором работаю, тут ТС 

//____________________________________________________________________
здесь опять все кратко и лаконично, но сделаю вывод в лог ошибки если возникнут при записи, сделаю именно здесь, т.к. только тут все модификации 
void CStrategy::SaveSelfStatus(const int handle)
{  FileWriteStruct(handle,m_setting);
   FileWriteStruct(handle,m_order_info);

}

 
Dmitry Fedoseev:

O tal vez no entendí nada.

Creo que no entendí nada, leí el artículo en diagonal el mes pasado, lo volví a retomar este mes, pero necesito probar para ver la viabilidad

Hubr:¿Singleton o clase estática?

Singleton (Одиночка) или статический класс?
Singleton (Одиночка) или статический класс?
  • habr.com
Статья будет полезна в первую очередь разработчикам, которые теряются на собеседованиях когда слышат вопрос «Назовите основные отличия синглтона от статического класса, и когда следует использовать один, а когда другой?». И безусловно будет полезна для тех разработчиков, которые при слове «паттерн» впадают в уныние или просят прекратить...
 
Igor Makanu:

- Problema: Estoy tratando de alejarme de la variable estática con la esperanza de que haya un truco Jedi OOP que no conozco

¿Por qué es un problema? No es necesario que te alejes de una variable estática si la necesitas.

Sigo sin entender de qué depende el indicador de necesidad de escritura.

En mi ejemplo se establece si ha habido cambios.

¿Cómo lo quieres poner?

 
Koldun Zloy:

¿Por qué es un problema? No tienes que alejarte de una variable estática si la necesitas.

¡entonces el problema está resuelto! - Así es como se hacía originalmente.

ZS: ya ha empezado a experimentar con la estructura estática... Sólo veo problemas con la inicialización, a continuación, con la legibilidad del código, he intentado variantes flag.saveRequired, a continuación, flagsave.Required, entonces me metí en operador de sobrecarga =, de todos modos, sin sentido todo esto. Es mucho más fácil y legible el código al final si lo haces a través de una variable privada estática y le añades setter y getter, pero como dicen: no buscamos caminos fáciles.... todo lo mejor para los autores de vídeos oscuros...

 
Fast235:

Ahora no es extraño por qué no hay suficiente Volchanskiy aquí, tipo duro Insider vista previa o lo que sea que utiliza))

He descargado win 10home desde el sitio off hace 3 meses, ni siquiera tuvo tiempo para configurar los ajustes básicos, el icono de opciones de inicio no se abre, sí ***********

Solo estoy ocupado y el foro consume mucho tiempo, no recomiendo instalarel Insider preview, ahora Vinda instala la nueva build una vez a la semana. Es mejor descargar la versión estable del sitio de MS. Es mi curiosidad infantil quesigue jugando en un lugar :)