Fragen zu OOP in MQL5 - Seite 39

 

Nun ist es nicht verwunderlich, warum es nicht genug Volchanskiy hier, tough guy Insider Vorschau oder was auch immer er verwendet))


Ich heruntergeladen win 10home aus dem Off-Site vor 3 Monaten, hatte nicht einmal Zeit, um die Grundeinstellungen zu konfigurieren, die Startoptionen Symbol nicht öffnen, ja ***********

 
Koldun Zloy:

Hier ist ein Beispiel:

Versucht, Ihr Beispiel vollständig auf meine Aufgabe anwenden, aber wieder die gleiche Rake - ich möchte am Ende mit dem "Datensatz erforderlich" Flag beim Erstellen eines neuen Nachkommen von einer Basisklasse:

//+------------------------------------------------------------------+
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

für jetzt alles, was funktioniert hat:

1. die Nichtangabe von Schnittstellen war überhaupt kein Problem

2. ich habe viele Setter und Getter erzeugt, konnte aber nicht von statischen Variablen wegkommen


Ich habe versucht, den Code noch einmal neu zu schreiben:

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

das Ergebnis ist das gleiche wie in der ersten Version, nur dass ich von den Schnittstellen weggekommen bin

 
Was ist das Ziel, was soll erreicht werden?
 
Dmitry Fedoseev:
Was ist das Ziel, was wollen Sie erreichen?

alles funktioniert, aber das Ziel ist es, Wissen zu erlangen ))))

wie ich es gemacht habe:

- es gibt eine Basisklasse, in der alle Berechnungen und TC-Einstellungen gespeichert werden, von ihr erben wir Nachkommen, die mit ihrem TC arbeiten

- Ich denke, es ist sinnvoll, die Datei in einer Datei zu speichern, indem man den Handle der geöffneten Datei an alle Nachkommen weitergibt; in diesem Fall erscheint die save()-Methode wieder in der Basisklasse

- das Speichern sollte erfolgen, wenn ein Ereignis/Flag auftritt - man weiß nicht, welcher Nachkomme es auslöst und wann, aber es ist schneller, Dutzende von Strukturen in einer neuen Datei zu speichern, als es herauszufinden

- warum nicht eine Klasse und eine Reihe von Einstellungen? - Ich muss ein oder zwei Methoden als virtuell deklarieren und sie zu jeder TS hinzufügen.

- das Problem: ich versuche, von statischen Variablen wegzukommen, in der Hoffnung, dass es einen Jedi OOP-Trick gibt, den ich nicht kenne





HH: Const Modifiers sind eine gute Sache, ich bereue die aufgewendete Zeit nicht - nützlich, danke nochmals für die Diskussion!

 

Wenn Sie Daten von allen Objekten dieser Klasse in eine Datei schreiben müssen, die einmal geöffnet wird, dann geht das nicht ohne eine statische Variable. Und warum sollte man es loswerden, wenn es für die Aufgabe am besten geeignet ist? Natürlich können Sie auch eine globale Variable deklarieren.

Was wäre, wenn jedes Objekt eine Datei öffnen, schreiben und schließen würde? Dann würde es genügen, in jedem Objekt einen Dateinamen zu haben... Aber auch in diesem Fall ist es besser, eine statische Variable zu verwenden, da der Wert der Variable immer und überall derselbe ist.

Oder ich verstehe gar nichts)

 
Dmitry Fedoseev:

Wenn Sie Daten von allen Objekten dieser Klasse in eine Datei schreiben müssen, die einmal geöffnet wird, dann geht das nicht ohne eine statische Variable. Und warum sollte man es loswerden, wenn es für die Aufgabe am besten geeignet ist? Natürlich können Sie auch eine globale Variable deklarieren.

Was wäre, wenn jedes Objekt eine Datei öffnen, schreiben und schließen würde? Dann würde es genügen, in jedem Objekt einen Dateinamen zu haben... Aber auch in diesem Fall ist es besser, eine statische Variable zu verwenden, da der Wert der Variable immer und überall derselbe ist.

Oder vielleicht habe ich es falsch verstanden)

In die Datei, die einmal geöffnet wird, schreiben wir Daten hinein und schließen sie sofort wieder, um keine Daten zu verlieren, wenn sich das Terminal aufhängt, wobei die Aufzeichnung von einmal pro Minute bis einmal pro Stunde reicht - es macht keinen Sinn, die Datei so lange offen zu halten.

Lassen Sie uns das im Code machen, so ist es jetzt:

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

Vielleicht habe ich aber auch gar nichts verstanden.

Ich glaube nicht, dass ich irgendetwas verstanden habe, ich habe den Artikel letzten Monat diagonal gelesen, bin diesen Monat noch einmal darauf zurückgekommen, muss aber die Machbarkeit prüfen

Hubr:Singleton oder statische Klasse?

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

- Problem: Ich versuche, von der statischen Variable wegzukommen, in der Hoffnung, dass es einen Jedi-OOP-Trick gibt, den ich nicht kenne

Warum ist das ein Problem? Sie brauchen nicht auf eine statische Variable zu verzichten, wenn Sie sie brauchen.

Ich verstehe immer noch nicht, wovon das Write Need Flag abhängt.

In meinem Beispiel ist sie gesetzt, wenn es Änderungen gegeben hat.

Wie wollen Sie es einstellen?

 
Koldun Zloy:

Warum ist das ein Problem? Sie müssen nicht auf eine statische Variable verzichten, wenn Sie eine benötigen.

dann ist das Problem gelöst! - So wurde es ursprünglich auch gemacht.

ZS: hat bereits begonnen, mit der statischen Struktur zu experimentieren... Ich sehe nur Probleme mit der Initialisierung, dann mit der Lesbarkeit des Codes, habe ich versucht, Varianten flag.saveRequired, dann flagsave.Required, dann habe ich in Überlast-Operator =, jedenfalls Unsinn all dies. Es ist viel einfacher und lesbarer Code am Ende, wenn Sie es über private statische Variable und fügen Sie Setter und Getter zu, aber wie sie sagen: wir sind nicht auf der Suche nach einfachen Möglichkeiten.... alles Gute für die Autoren der obskuren Videos...

 
Fast235:

Nun ist es nicht verwunderlich, warum es nicht genug Volchanskiy hier, tough guy Insider Vorschau oder was auch immer er verwendet))

Ich heruntergeladen win 10home aus dem Off-Site vor 3 Monaten, hatte nicht einmal Zeit, um die Grundeinstellungen zu konfigurieren, die Startoptionen Symbol nicht öffnen, ja ***********

Nur beschäftigt und Forum ist zeitaufwendig, ich empfehle nicht,Insider Preview zu installieren, jetzt Vinda installiert neue Build einmal pro Woche. Besser ist es, die stabile Version von der MS-Website herunterzuladen. Es ist meine kindliche Neugier, dieimmer noch an einem Ort spielt :)