Errori, bug, domande - pagina 2657

 
Stanislav Korotky:

Questo è il punto, l'albero delle classi ha un nodo comune CWnd (CObject è più lontano, alla radice).

CButton -> CWndObj -> CWnd -> CObject.

Se si cambia il parametro nel metodo in CObject, si ottengono 2 volte più errori:

Una gerarchia di classi simile funziona per il caso non-array. Ecco il codice compilato:

La domanda è come farlo funzionare anche per un array?

So che un modello aiuta, ma voglio solo evitarlo.

IMHO, dovrebbe funzionare senza modelli per diritto di eredità.

L'ho controllato come in C++.

Funziona. Ma MQL non lo digerisce - sia con che senza l'indice.

Per il C++, il tuo esempio sarà molto più chiaro. Basta eseguirlo e vedere cosa succede)))

class CWnd
{
public:
    int x;
    CWnd(int _x = 10) : x(_x) {}
};
class CButton : public CWnd
{
    int a;
public:
    CButton(int _a=6) : CWnd(),a(_a) {}
};

class Collection
{
public:
    Collection(CWnd* ptr,size_t size) {
        for (int i = 0; i < size; cout << ptr[i++].x<<endl);
    }
};

int main()
{
    CButton buttons[10];
    CWnd wnd[10];
    Collection data1(&wnd[0],_countof(wnd));
    cout << "------------------------------" << endl;
    Collection data2(&buttons[0],_countof(buttons));
    return 0;
}
 

Sì, colpa mia. Ma poi sorge la seguente domanda. Questo codice C++ funziona (già esattamente giusto ;-)).

class Base
{
  public:
    virtual void method1(void) { cout << "2\n"; }
};

class Derived: public Base
{
  public:
    virtual void method1(void) override { cout << "3\n"; }
};

template<typename T>
class Wrapper
{
  public:
    Wrapper(T *ptr)
    {
      ptr->T::method1();
    }
};

int main()
{
  Derived d;
  d.Base::method1();   // ok
  Wrapper<Base> w(&d); // ok

  return 0;
}

MQL simile dà errore:

class Base
{
  public:
    virtual void method1(void) { Print(__FUNCSIG__); }
};

class Derived: public Base
{
  public:
    virtual void method1(void) override { Print(__FUNCSIG__); }
};

template<typename T>
class Wrapper
{
  public:
    Wrapper(T *ptr)
    {
      ptr.T::method1(); // <<< 'Base' is not a class, struct or union
    }
};


void OnStart()
{
  Derived d;
  d.Base::method1();   // ok
  Wrapper<Base> w(&d); // causes the error above
 
Stanislav Korotky:

Sì, colpa mia. Ma poi sorge la seguente domanda. Questo codice C++ funziona (già esattamente giusto ;-)).

Un MQL simile dà un errore:

Non conosco il compito, ma credo che tu stia cercando qualcosa del genere:

typedef void(*PTR)(void);

in MQL questo è un puntatore a una funzione void func(void)

in una classe, potete dichiarare un campo di tipo PTR e poi assegnargli una funzione, e poi "dereferenziare il puntatore" e chiamare la funzione

Passare funzioni scritte in stile procedurale nella classe funziona senza problemi, i metodi di classe probabilmente non possono essere passati così facilmente, si può provare a usare dynamic_cast, ma il codice diventerà molto confuso

 
Igor Makanu:

Non conosco il compito, ma credo che tu stia cercando qualcosa di simile a questo:

in MQL è un puntatore a una funzione void func(void)

in una classe, potete dichiarare un campo di tipo PTR e poi assegnargli una funzione e poi "dereferenziare il puntatore" e chiamare la funzione

Passare funzioni scritte in stile procedurale nella classe funziona senza problemi, i metodi di classe probabilmente non possono essere passati così facilmente, si può provare a usare dynamic_cast, ma il codice diventerà molto confuso

typedef non funziona con un metodo.

dynamic_cast funziona verso l'erede (catena più lunga), cioè, se il puntatore alla base contiene il derivato, allora si può fare il cast al derivato e se non è NULL (cioè cast normale), chiamare il suo metodo. Ma quando la situazione è opposta, come nel mio caso, c'è il puntatore alla derivata allora è per definizione anche base. E qualsiasi invocazione del suo metodo virtuale scopre che la derivata è "seduta" nel puntatore e chiama l'implementazione sovrascritta. La base è necessaria.

C'è il suddetto costrutto sintattico in C++ per questo scopo, ma MQL non è C++. A quanto pare non c'è ancora un modo per farlo.

Ho fatto un workaround ma potrebbe non funzionare bene in tutti i compiti.

Il punto di tutta questa danza del tamburello, come sempre, è quello di mantenere il codice aggrovigliato all'interno della "libreria" e rendere il codice che la usa cristallino e semplice.

 

con cosa inizializzare rand() nel tester?

codice:

input ulong param = 18446744073709551615;
void OnTick()
   {
   }
//+------------------------------------------------------------------+
double OnTester()
   {
      srand(GetTickCount()); 
      return(rand());
   }
//+------------------------------------------------------------------+

Non mi piace molto questo tipo di generazione pseudo-casuale:


 
Igor Makanu:

con cosa inizializzare rand() nel tester?

codice:

Non mi piace molto questo tipo di generazione pseudorandom:


Aiuto:MathRand

Nota

Prima di chiamare la funzione per la prima volta, è necessario utilizzareMathSrand per impostare il generatore di numeri pseudocasuali allo stato iniziale.


Provatelo ora con MathSrand.

Документация по MQL5: Математические функции / MathRand
Документация по MQL5: Математические функции / MathRand
  • www.mql5.com
Математические функции / MathRand - справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
 
Vladimir Karputov:

Riferimento:MathRand

Nota

La funzioneMathSrand deve essere usata prima della prima chiamata di funzione per impostare il generatore di numeri pseudocasuali allo stato iniziale.

Grazie Cap!

Stiamo parlando del tester.

Questo codice non funziona nemmeno nel tester

input ulong param = 18446744073709551615;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
   {
   MathSrand(GetTickCount()); 
   return(INIT_SUCCEEDED);
   }
//+------------------------------------------------------------------+
void OnTick()
   {
   }
//+------------------------------------------------------------------+
double OnTester()
   {
      return(rand());
   }
//+------------------------------------------------------------------+
 
Igor Makanu:

Penso che, se un tester, non c'è bisogno di usare MathSrand.

Ma se questo non aiuta, allora molto probabilmente il tester sta forzando MathSrand(GetTickCount()) ad un certo punto.

Allora provate MathSrand(int(GetMicrosecondCount()%1000000));

Ricordate, GetTickCount() cambia il suo valore ogni 15,625 millisecondi. È un intervallo di tempo molto lungo per un tester.

 
Nikolai Semko:

Penso che, se un tester, non c'è bisogno di usare MathSrand.

questo contraddice la documentazionehttps://www.mql5.com/ru/docs/math/mathrand

Prima della prima chiamata di funzione, è necessario utilizzare la funzione MathSrand per impostare il generatore di numeri pseudorandom allo stato iniziale.

Non voglio esaminare il codice sorgente, ma per i pacchetti di reti neurali l'inizializzazione con un valore casuale dei pesi NS è obbligatoria, sospetto che questo sia stato fatto secondo il materiale di aiuto MQL - cioè è stato usato srand()

cioè l'uso di programmi MQL all'interno del tester con tale pacchetto NS avverrà molto probabilmente su un core del processore - i pesi iniziali NS avranno gli stessi valori, giusto?

è ancora più figo senza srand()

int OnInit()
   {
   return(INIT_SUCCEEDED);
   }
//+------------------------------------------------------------------+
void OnTick()
   {
   }
//+------------------------------------------------------------------+
double OnTester()
   {
      return(rand());
   }
//+------------------------------------------------------------------+
 
Igor Makanu:

questo contraddice la documentazionehttps://www.mql5.com/ru/docs/math/mathrand

Non voglio guardare il codice sorgente, ma per i pacchetti di reti neurali l'inizializzazione con un valore casuale dei pesi NS è obbligatoria, sospetto che questo sia stato fatto secondo il materiale di aiuto MQL - cioè è stato usato srand()

cioè l'uso di programmi MQL all'interno del tester con tale pacchetto NS avverrà molto probabilmente su un core del processore - i pesi iniziali NS avranno gli stessi valori, giusto?

ancora più divertente senza srand()

Igor, allora prova MathSrand(int(GetMicrosecondCount()%16384));

Mi chiedo come cambierà l'immagine.