Domande su OOP in MQL5 - pagina 39

 

Ora non è strano perché non c'è abbastanza Volchanskiy qui, duro Insider preview o qualsiasi cosa usi))


Ho scaricato win 10home dal sito off 3 mesi fa, non ho avuto nemmeno il tempo di configurare le impostazioni di base, l'icona delle opzioni di avvio non si apre, sì ***********

 
Koldun Zloy:

Ecco un esempio:

Ho provato ad applicare completamente il tuo esempio al mio compito, ma di nuovo lo stesso rastrellamento - voglio finire con il flag "record richiesto" quando si crea un nuovo discendente da una 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

per ora tutto ciò che ha funzionato:

1. non dichiarare le interfacce non era affatto un problema

2. Ho generato un sacco di setter e getter ma non sono riuscito a liberarmi delle variabili statiche


Ho provato a riscrivere di nuovo il codice:

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

il risultato è lo stesso della prima versione, l'unica cosa è che mi sono allontanato dalle interfacce

 
Qual è l'obiettivo, cosa si vuole ottenere?
 
Dmitry Fedoseev:
Qual è l'obiettivo, cosa vuoi ottenere?

tutto funziona, ma l'obiettivo è quello di acquisire conoscenze ))))

come ho fatto:

- c'è una classe base in cui tutti i calcoli e memorizza le impostazioni TC, da essa ereditiamo i discendenti che lavorano con il loro TC

- Penso che sia ragionevole salvare il file in un file passando l'handle del file aperto a tutti i discendenti; in questo caso, il metodo save() appare di nuovo nella classe base

- il salvataggio dovrebbe essere eseguito quando si verifica un evento/flag - non si sa quale discendente lo inizia e quando, ma è più veloce salvare decine di strutture in un nuovo file che capirlo

- perché non fare una classe e un array di impostazioni? - Devo dichiarare uno o due metodi come virtuali e aggiungerli ad ogni TS.

- il problema: sto cercando di allontanarmi dalle variabili statiche nella speranza che ci sia un trucco jedi OOP che non conosco





SZY: i modificatori const sono una buona cosa, non rimpiango il tempo speso - utile, grazie ancora per la discussione!

 

Se dovete scrivere i dati di tutti gli oggetti di questa classe in un file, che viene aperto una sola volta, allora non potete farlo senza una variabile statica. E perché sbarazzarsene, se si adatta meglio al compito? Naturalmente, potete anche dichiarare una variabile globale.

E se ogni oggetto potesse aprire, scrivere e chiudere un file? Allora sarebbe sufficiente avere un nome di file in ogni oggetto... Ma anche in questo caso è meglio usare una variabile statica, perché il valore della variabile è sempre lo stesso ovunque.

O non capisco niente)

 
Dmitry Fedoseev:

Se dovete scrivere i dati di tutti gli oggetti di questa classe in un file, che viene aperto una sola volta, allora non potete farlo senza una variabile statica. E perché sbarazzarsene, se si adatta meglio al compito? Naturalmente, potete anche dichiarare una variabile globale.

E se ogni oggetto potesse aprire, scrivere e chiudere un file? Allora sarebbe sufficiente avere un nome di file in ogni oggetto... Ma anche in questo caso è meglio usare una variabile statica, perché il valore della variabile è sempre lo stesso ovunque.

O forse mi sono sbagliato)

Nel file, che viene aperto una volta, ci scriviamo i dati e lo chiudiamo immediatamente, per non perdere i dati se il terminale si blocca, registrando da una volta al minuto a una volta all'ora - non ha senso tenere il file aperto per così tanto tempo

Facciamolo in codice, è così che è ora:

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

Non credo di aver capito nulla, ho letto l'articolo in diagonale il mese scorso, ci sono ritornato questo mese, ma ho bisogno di testare per vedere la fattibilità

Hubr:Singleton o classe statica?

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

- Problema: sto cercando di allontanarmi dalla variabile statica nella speranza che ci sia un trucco Jedi OOP che non conosco

Perché questo è un problema? Non c'è bisogno di allontanarsi da una variabile statica se ne avete bisogno.

Non ho ancora capito da cosa dipende il flag di necessità di scrittura.

Nel mio esempio è impostato se ci sono stati cambiamenti.

Come vuoi che sia impostato?

 
Koldun Zloy:

Perché questo è un problema? Non dovete rinunciare a una variabile statica se ne avete bisogno.

allora il problema è risolto! - È così che è stato fatto in origine.

ZS: già iniziato a sperimentare con la struttura statica... Vedo solo problemi con l'inizializzazione, poi con la leggibilità del codice, ho provato le varianti flag.saveRequired, poi flagsave.Required, poi sono entrato in overload operator =, comunque, senza senso tutto questo. È molto più facile e leggibile il codice alla fine se lo fai tramite una variabile statica privata e ci aggiungi setter e getter, ma come si dice: non stiamo cercando modi facili.... tutto il meglio agli autori di video oscuri...

 
Fast235:

Ora non è strano perché non c'è abbastanza Volchanskiy qui, duro Insider preview o qualsiasi cosa usi))

Ho scaricato win 10home dal sito off 3 mesi fa, non ho avuto nemmeno il tempo di configurare le impostazioni di base, l'icona delle opzioni di avvio non si apre, sì ***********

Solo occupato e il forum richiede tempo, non consiglio di installare l'anteprima Insider, ora Vinda installa la nuova build una volta alla settimana. Meglio scaricare la build stabile dal sito MS. È la mia curiosità infantile che giocaancora in un posto :)