Fehler, Irrtümer, Fragen - Seite 2657

 
Stanislav Korotky:

Das ist die Sache, der Klassenbaum hat einen gemeinsamen Knoten CWnd (CObject ist weiter weg, an der Wurzel).

CButton -> CWndObj -> CWnd -> CObject.

Wenn Sie den Parameter in der Methode in CObject ändern, erhalten Sie 2 mal mehr Fehler:

Eine ähnliche Klassenhierarchie gilt für den Fall, dass es sich nicht um ein Array handelt. Hier ist der kompilierte Code:

Die Frage ist, wie man das auch für ein Array hinbekommt?

Ich weiß, dass eine Vorlage hilfreich ist, aber ich möchte es einfach vermeiden.

IMHO sollte es ohne Vorlagen durch Vererbungsrecht funktionieren.

Ich habe es wie in C++ überprüft.

Es funktioniert. Aber MQL verdaut es nicht - sowohl mit als auch ohne den Index.

Für C++ wird Ihr Beispiel viel klarer sein. Lassen Sie es einfach laufen und sehen Sie, was passiert)))

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;
}
 

Ja, mein Fehler. Doch dann stellt sich die folgende Frage. Dieser C++-Code funktioniert (schon genau richtig ;-)).

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;
}

Ähnliche MQL gibt Fehler:

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:

Ja, mein Fehler. Doch dann stellt sich die folgende Frage. Dieser C++-Code funktioniert (schon genau richtig ;-)).

Eine ähnliche MQL gibt einen Fehler:

Ich kenne die Aufgabe nicht, aber ich glaube, Sie suchen etwas in dieser Art:

typedef void(*PTR)(void);

in MQL ist dies ein Zeiger auf eine void func(void) Funktion

in einer Klasse kann man ein Feld vom Typ PTR deklarieren und ihm dann eine Funktion zuweisen, die dann den Zeiger "dereferenziert" und die Funktion aufruft

Die Übergabe von prozedural geschriebenen Funktionen in die Klasse funktioniert problemlos, die Methoden der Klasse können wahrscheinlich nicht so einfach übergeben werden, man kann es mit dynamic_cast versuchen, aber der Code wird dann sehr unübersichtlich

 
Igor Makanu:

Ich kenne die Aufgabe nicht, aber ich denke, Sie suchen etwas in dieser Art:

in MQL ist es ein Zeiger auf eine void func(void) Funktion

in einer Klasse können Sie ein Feld vom Typ PTR deklarieren, ihm eine Funktion zuweisen, den Zeiger "dereferenzieren" und die Funktion aufrufen

Die Übergabe von prozedural geschriebenen Funktionen in die Klasse funktioniert problemlos, die Methoden der Klasse können wahrscheinlich nicht so einfach übergeben werden, man kann es mit dynamic_cast versuchen, aber der Code wird dann sehr unübersichtlich

typedef wird nicht mit einer Methode funktionieren.

dynamic_cast arbeitet in Richtung Erbe (längere Kette), das heißt, wenn Zeiger auf Basis enthält abgeleitet, dann können Sie zu abgeleitet casten und wenn es nicht NULL (dh Cast normal), rufen Sie seine Methode. Aber wenn die Situation umgekehrt ist, wie in meinem Fall, gibt es Zeiger auf abgeleitet, dann ist es per Definition auch Basis. Und jeder Aufruf seiner virtuellen Methode findet heraus, dass derived in dem Zeiger "sitzt" und ruft die überschriebene Implementierung auf. Die Basis wird benötigt.

In C++ gibt es das oben erwähnte Syntaxkonstrukt für diesen Zweck, aber MQL ist nicht C++. Offenbar gibt es noch keine Möglichkeit, dies zu tun.

Ich habe eine Umgehungslösung gefunden, die aber möglicherweise nicht bei allen Aufgaben gut funktioniert.

Der Sinn dieses Tamburin-Tanzes besteht wie immer darin, den verworrenen Code innerhalb der "Bibliothek" zu halten und den Code, der sie verwendet, kristallklar und einfach zu gestalten.

 

Womit soll rand() im Testgerät initialisiert werden?

Code:

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

Ich mag diese Art der Pseudo-Zufallsgenerierung nicht wirklich:


 
Igor Makanu:

Womit soll rand() im Testgerät initialisiert werden?

Code:

Ich mag diese Art der Pseudo-Zufallsgenerierung nicht wirklich:


Hilfe:MathRand

Hinweis

Bevor Sie die Funktion zum ersten Mal aufrufen, müssen SieMathSrand verwenden, um den Pseudozufallszahlengenerator in den Anfangszustand zu versetzen.


Probieren Sie es jetzt mit MathSrand.

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

Hilfe:MathRand

Hinweis

DieMathSrand-Funktion muss vor dem ersten Funktionsaufruf verwendet werden, um den Pseudozufallszahlengenerator in den Anfangszustand zu versetzen.

Danke Cap!

Wir sprechen über den Prüfer.

dieser Code funktioniert auch im Tester nicht

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

Ich denke, dass, wenn ein Prüfer, gibt es keine Notwendigkeit, MathSrand verwenden.

Aber wenn das nicht hilft, dann erzwingt der Prüfer höchstwahrscheinlich an irgendeiner Stelle MathSrand(GetTickCount()).

Versuchen Sie dann MathSrand(int(GetMicrosecondCount()%1000000));

Zur Erinnerung: GetTickCount() ändert seinen Wert alle 15,625 Millisekunden. Das ist eine sehr lange Zeitspanne für einen Prüfer.

 
Nikolai Semko:

Ich denke, dass, wenn ein Prüfer, gibt es keine Notwendigkeit, MathSrand verwenden.

dies widerspricht der Dokumentationhttps://www.mql5.com/ru/docs/math/mathrand

Vor dem ersten Funktionsaufruf müssen Sie die Funktion MathSrand verwenden, um den Pseudozufallszahlengenerator in den Anfangszustand zu versetzen.

Ich möchte nicht durch den Quellcode zu gehen, aber für neuronale Netzwerk-Pakete Initialisierung durch zufällige Wert der NS-Gewichte ist obligatorisch, ich vermute, dass dies nach MQL-Hilfsmaterial getan wurde - dh srand() verwendet wurde

d.h. die Verwendung von MQL-Programmen innerhalb des Testers mit einem solchen NS-Paket wird höchstwahrscheinlich auf einem Prozessorkern stattfinden - die anfänglichen NS-Gewichte werden die gleichen Werte haben, richtig?

ohne srand() ist es noch cooler

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

dies widerspricht der Dokumentationhttps://www.mql5.com/ru/docs/math/mathrand

Ich möchte nicht durch den Quellcode zu sehen, aber für neuronale Netzwerk-Pakete Initialisierung durch zufällige Wert der NS-Gewichte ist obligatorisch, ich vermute, dass dies nach MQL-Hilfsmaterial getan wurde - dh srand() verwendet wurde

d.h. die Verwendung von MQL-Programmen innerhalb des Testers mit einem solchen NS-Paket wird höchstwahrscheinlich auf einem Prozessorkern stattfinden - die anfänglichen NS-Gewichte werden die gleichen Werte haben, richtig?

noch lustiger ohne srand()

Igor, dann versuchen Sie MathSrand(int(GetMicrosecondCount()%16384));

Ich frage mich, wie sich das Bild verändern wird.

Grund der Beschwerde: