Perguntas sobre OOP em MQL5 - página 39

 

Agora não é estranho por que não há Volchanskiy suficiente aqui, durão de prever Insider ou o que quer que ele use))


Eu baixei 10home do off site 3 meses atrás, nem tive tempo de configurar as configurações básicas, o ícone de Opções de inicialização não abre, sim ***********

 
Koldun Zloy:

Aqui está um exemplo:

Tentei aplicar plenamente seu exemplo à minha tarefa, mas novamente o mesmo ancinho - quero terminar com a bandeira "recorde exigido" ao criar um novo descendente de uma classe 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 enquanto, tudo o que funcionou:

1. Não declarar interfaces não foi um problema de forma alguma

2. gerei muitos setters e getters, mas não consegui me afastar das variáveis estáticas.


Eu tentei reescrever o código novamente:

//+------------------------------------------------------------------+
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);
  }

o resultado é o mesmo que na primeira versão, a única coisa é que eu me afastei das interfaces

 
Qual é o objetivo, o que se deve ganhar?
 
Dmitry Fedoseev:
Qual é o objetivo, o que você quer obter?

tudo funciona, mas o objetivo é ganhar conhecimento ))))

como eu o fiz:

- há uma classe base na qual todos os cálculos e ela armazena as configurações TC, a partir dela herdamos descendentes que trabalham por seus TC

- Acho razoável salvar o arquivo em um arquivo passando o cabo do arquivo aberto para todos os descendentes; neste caso, o método save() aparece novamente na classe base

- A economia deve ser realizada quando ocorre um evento/bandeira - você não sabe qual descendente a inicia e quando, mas é mais rápido salvar dezenas de estruturas em um novo arquivo do que descobri-lo

- por que não fazer uma classe e um conjunto de configurações? - Tenho que declarar um ou dois métodos como virtuais e adicioná-los a cada TS.

- o problema: estou tentando fugir das variáveis estáticas na esperança de que haja um truque do OOP jedi que eu não conheço.





SZY: os modificadores constantes são uma coisa boa, não me arrependo do tempo gasto - útil, obrigado novamente pela discussão!

 

Se você tem que escrever dados de todos os objetos desta classe em um arquivo, que é aberto uma vez, então você não pode fazer isso sem uma variável estática. E por que se livrar dela, se ela se adequa melhor à tarefa? É claro, você também pode declarar uma variável global.

E se cada objeto abrisse, escrevesse e fechasse um arquivo? Então seria suficiente ter um nome de arquivo em cada objeto. Mas também neste caso é melhor usar uma variável estática, porque o valor da variável é sempre o mesmo em todos os lugares.

Ou eu não entendo nada)

 
Dmitry Fedoseev:

Se você tem que escrever dados de todos os objetos desta classe em um arquivo, que é aberto uma vez, então você não pode fazer isso sem uma variável estática. E por que se livrar dela, se ela se adequa melhor à tarefa? É claro, você também pode declarar uma variável global.

E se cada objeto abrisse, escrevesse e fechasse um arquivo? Então seria suficiente ter um nome de arquivo em cada objeto. Mas também neste caso é melhor usar uma variável estática, porque o valor da variável é sempre o mesmo em todos os lugares.

Ou talvez eu tenha entendido errado)

No arquivo, que é aberto uma vez, escrevemos dados nele e imediatamente fechamos, para não perder dados se o terminal desligar, registrando de uma vez por minuto a uma vez por hora - não faz sentido manter o arquivo aberto por tanto tempo

vamos fazê-lo em código, é assim que é agora:

// это один файл, его не трогаю, тут только конструктор и 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:

Ou talvez eu não tenha entendido nada.

Acho que não entendi nada, li o artigo diagonalmente no mês passado, voltei a ele este mês, mas preciso testar para ver a viabilidade

Hubr:Classe singleton ou estática?

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

- Problema: Estou tentando me afastar da variável estática na esperança de que haja um truque do OOP Jedi que eu não conheço.

Por que isso é um problema? Você não precisa se afastar de uma variável estática se precisar dela.

Eu ainda não entendo do que depende a bandeira de necessidade de escrita.

No meu exemplo, se houverem mudanças, elas serão definidas.

Como você quer que seja ajustado?

 
Koldun Zloy:

Por que isso é um problema? Você não tem que se afastar de uma variável estática se precisar de uma.

então o problema é resolvido! - Foi assim que foi feito originalmente.

ZS: já começou a experimentar a estrutura estática... Vejo apenas problemas com inicialização, depois com legibilidade do código, tentei variantes flag.saveRequired, depois flagsave.Required, depois entrei em sobrecarga operator =, de qualquer forma, bobagem, tudo isso. No final, é muito mais fácil e legível se você o fizer através de uma variável estática privada e adicionar setter e getter a ela, mas como eles dizem: não estamos procurando maneiras fáceis.... tudo de bom para os autores de vídeos obscuros...

 
Fast235:

Agora não é estranho por que não há Volchanskiy suficiente aqui, durão de prever Insider ou o que quer que ele use))

Eu baixei 10home do off site 3 meses atrás, nem tive tempo de configurar as configurações básicas, o ícone de Opções de inicialização não abre, sim ***********

Apenas ocupado e o fórum é demorado, eu não recomendo a instalação deInsider preview, agora Vinda instala novo build uma vez por semana. É melhor baixar a construção estável do site da MS. É minha curiosidade infantilainda brincando em um só lugar :)