Domande su OOP in MQL5 - pagina 35

 
Roman:

Se l'oggetto ha completato il suo compito, perché tenerlo in memoria?
Non ci sarà una perdita di memoria?

Lo farà, specialmente se non viene cancellato nemmeno in OnDeinit.
Non dovete conservarlo in memoria, se davvero non vi serve più. Ma più spesso succede che un oggetto viene creato e usato in una sola iterazione... E poi alla seconda iterazione... E così via. E poi, in certe condizioni, si crea un altro oggetto della stessa classe, e si lavora già con due o più oggetti di questa classe, ognuno dei quali è necessario durante la vita dell'EA.

 
BlackTomcat:

Si verificherà, specialmente se non viene cancellato nemmeno in OnDeinit.
Non dovete conservarlo in memoria, se davvero non vi serve più. Ma più spesso succede che un oggetto viene creato e usato in una sola iterazione... E poi alla seconda iterazione... E così via. E poi, in certe condizioni, si crea un altro oggetto della stessa classe, e si lavora già con due o più oggetti di questa classe, ognuno dei quali è necessario durante la vita dell'EA.

Quindi volete dire che una perdita di memoria controllata è meglio che ricreare gli oggetti?
Cioè, risparmiare tempo, in cambio di demoni controllati?
È pericoloso non perderli dopo.

 

ha scritto usando il modellohttps://www.mql5.com/ru/forum/85652/page24#comment_13054686 dell'esperto

un modello abbastanza flessibile, permette di aggiungere diversi "plus" in "2 click" e il codice risulta leggibile e logico, ma... Sono tornato a qualche paradigma discusso che una buona classe, beh, non dovrebbe avere metodi statici

Sembra bello in teoria, ma in pratica... Non secondo me, almeno per i problemi MQL, imho.

Secondo il modello, la classe EA è stata scritta e un metodo pubblico viene avviato in OnTick(). Ma durante l'inizializzazione dell'EA, voglio controllare se ci sono ordini aperti e prenderli:

1. scrivere una funzione nel seguente OnTick() che se trova un ordine aperto tramite la procedura guidata, crea un oggetto EA; se non viene trovato nessun ordine, l'oggetto EA viene inizializzato secondo la logica di base - l'oggetto EA viene creato solo nel tempo di trading e implementa la logica del TS nel futuro

2. Scrivere una classe statica in EA, che implementa gli elementi 1


Essenzialmente i punti 1 e 2 sono gli stessi, la differenza è che nel passo 1, aggiungo una funzione che avrebbe senso solo durante l'inizializzazione dell'EA (la prima esecuzione), ma imho, sovraccarica il codice - una funzione sarà chiamata una volta per l'intera esecuzione del programma!

se fai un metodo statico ( pp.2 ), allora sarà logico e leggibile - il metodo è necessario solo per l'inizializzazione e definisce il momento in cui l'oggetto EA dovrebbe essere creato - dovresti passare a questo metodo solo il numero magico.


A mio avviso proibire di usare metodi statici quando è conveniente... a dir poco sbagliato!

 
Igor Makanu:

Imetodi statici differiscono dalle funzioni solo per il loro ambito.


Questa pratica è pericolosa

input int inInput = 0;

const bool Init = EventSetTimer(1);

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


Se cambi l'ingresso mentre l'EA è in esecuzione, l'ingresso non cambierà.

Di conseguenza, è irto di

input long inMagic = 0;

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

Se si cambia l'input mentre EA è in esecuzione, l'input non cambierà.

Ne sono consapevole, e nel mio TS non si possono cambiare i parametri di input mentre EA sta lavorando, il tempo di esecuzione è separato dalla logica del TS

La mia domanda è puramente teorica, non voglio sovraccaricare il codice, quindi sto cercando la possibilità di ripristinare il TS dopo un crash da qualche parte, finora lo vedo così:

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

Ha più senso spingere questa logica nel costruttore.

 
fxsaber:

Imetodi statici differiscono dalle funzioni solo per il loro ambito.

Errato: hanno anche accesso a membri e metodi non pubblici della classe.
 
TheXpert:
scorretto. anche l'accesso a membri e metodi non pubblici della classe.

Qui c'è un malinteso terminologico. "Area di visibilità" non riguarda solo chi vede il metodo. Ma anche quello che lui stesso vede.

 
fxsaber:

Qui c'è un malinteso terminologico.

Dopo tutto, la visibilità e l'accesso sono concetti diversi ed è meglio non confonderli
 
fxsaber:

Ha più senso mettere questa logica nel costruttore.

Sì, questa è una soluzione migliore! Così c'è un metodo in meno

È così che dovrebbe essere:

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:
dopo tutto, la visibilità e l'accesso sono concetti diversi ed è meglio non confonderli
Ecco perché ho una domanda, dove dovrei mettere un modo per rilevare che l'ultima esecuzione è andata in crash, ora la mia struttura di codice è compatta, tutto segue chiaramente lo schema che ho mostrato sopra