Questions sur la POO dans MQL5 - page 39

 

Maintenant, il n'est pas étrange pourquoi il n'y a pas assez de Volchanskiy ici, le dur à cuire Insider preview ou ce qu'il utilise)).


J'ai téléchargé win 10home depuis le site off il y a 3 mois, je n'ai même pas eu le temps de configurer les paramètres de base, l'icône Options de démarrage ne s'ouvre pas, oui ***********.

 
Koldun Zloy:

Voici un exemple :

J'ai essayé d'appliquer complètement votre exemple à ma tâche, mais à nouveau le même rake - je veux aboutir à l'indicateur "enregistrement requis" lors de la création d'un nouveau descendant à partir d'une classe de 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

pour l'instant tout ce qui a fonctionné :

1. la non-déclaration des interfaces n'était pas du tout un problème

2. j'ai généré beaucoup de setters et de getters mais je n'ai pas réussi à m'affranchir des variables statiques


J'ai essayé de réécrire le code à nouveau :

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

le résultat est le même que dans la première version, la seule chose est que je me suis éloigné des interfaces

 
Quel est l'objectif, qu'est-ce qu'il y a à gagner ?
 
Dmitry Fedoseev:
Quel est l'objectif, que voulez-vous obtenir ?

tout fonctionne, mais le but est d'acquérir des connaissances ))))

comment je l'ai fait :

- il y a une classe de base dans laquelle tous les calculs sont effectués et qui stocke les paramètres du CT, à partir de laquelle nous héritons des descendants qui fonctionnent par leur CT.

- Je pense qu'il est raisonnable de sauvegarder le fichier dans un seul fichier en passant le handle du fichier ouvert à tous les descendants ; dans ce cas, la méthode save() apparaît à nouveau dans la classe de base

- la sauvegarde doit être effectuée lorsqu'un événement/flag se produit - vous ne savez pas quel descendant l'initie et à quel moment, mais il est plus rapide de sauvegarder des dizaines de structures dans un nouveau fichier que de le découvrir.

- pourquoi ne pas créer une classe et un tableau de paramètres ? - Je dois déclarer une ou deux méthodes comme virtuelles et les ajouter à chaque TS.

- le problème : j'essaie de m'éloigner des variables statiques dans l'espoir qu'il existe une astuce jedi de POO que je ne connais pas.





SZY : les modificateurs de constantes sont une bonne chose, je ne regrette pas le temps passé - utile, merci encore pour la discussion !

 

Si vous devez écrire les données de tous les objets de cette classe dans un fichier, qui n'est ouvert qu'une fois, vous ne pouvez pas le faire sans une variable statique. Et pourquoi s'en débarrasser, si elle convient le mieux à la tâche ? Bien entendu, vous pouvez également déclarer une variable globale.

Et si chaque objet pouvait ouvrir, écrire et fermer un fichier ? Il suffirait alors d'avoir un nom de fichier dans chaque objet... Mais dans ce cas aussi, il est préférable d'utiliser une variable statique, car la valeur de la variable est toujours la même partout.

Ou je ne comprends rien)

 
Dmitry Fedoseev:

Si vous devez écrire les données de tous les objets de cette classe dans un fichier, qui n'est ouvert qu'une fois, vous ne pouvez pas le faire sans une variable statique. Et pourquoi s'en débarrasser, si elle convient le mieux à la tâche ? Bien entendu, vous pouvez également déclarer une variable globale.

Et si chaque objet pouvait ouvrir, écrire et fermer un fichier ? Il suffirait alors d'avoir un nom de fichier dans chaque objet... Mais dans ce cas aussi, il est préférable d'utiliser une variable statique, car la valeur de la variable est toujours la même partout.

Ou peut-être que je me suis trompé)

Dans le fichier, qui est ouvert une fois, nous écrivons des données et le fermons immédiatement, afin de ne pas perdre de données si le terminal raccroche, enregistrant d'une fois par minute à une fois par heure - il n'y a aucun sens à garder le fichier ouvert aussi longtemps.

faisons-le en code, c'est comme ça que ça se passe maintenant :

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

Ou peut-être que je n'ai rien compris.

Je ne pense pas avoir compris quoi que ce soit, j'ai lu l'article en diagonale le mois dernier, j'y suis revenu ce mois-ci, mais je dois faire un test pour voir la faisabilité.

Hubr :Singleton ou classe statique ?

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

- Problème : j'essaie de m'affranchir de la variable statique dans l'espoir qu'il existe une astuce de Jedi OOP que je ne connais pas.

Pourquoi est-ce un problème ? Il n'est pas nécessaire de renoncer à une variable statique si vous en avez besoin.

Je ne comprends toujours pas de quoi dépend le drapeau de besoin d'écriture.

Dans mon exemple, il est défini s'il y a eu des changements.

Comment voulez-vous qu'il soit réglé ?

 
Koldun Zloy:

Pourquoi est-ce un problème ? Vous n'êtes pas obligé de renoncer à une variable statique si vous en avez besoin.

alors le problème est résolu ! - C'est ainsi que cela a été fait à l'origine.

ZS : déjà commencé à expérimenter la structure statique... Je ne vois que des problèmes d'initialisation, puis de lisibilité du code, j'ai essayé les variantes flag.saveRequired, puis flagsave.Required, puis je me suis retrouvé dans l'opérateur de surcharge =, bref, un non-sens tout ça. Le code est beaucoup plus facile et lisible à la fin si vous le faites via une variable statique privée et que vous lui ajoutez un setter et un getter, mais comme on dit : nous ne cherchons pas de moyens faciles..... bonne chance aux auteurs de vidéos obscures...

 
Fast235:

Maintenant, il n'est pas étrange pourquoi il n'y a pas assez de Volchanskiy ici, tough guy Insider preview ou quoi qu'il utilise)).

J'ai téléchargé win 10home depuis le site off il y a 3 mois, je n'ai même pas eu le temps de configurer les paramètres de base, l'icône Options de démarrage ne s'ouvre pas, oui ***********.

Je suis occupé et le forum prend du temps, je ne recommande pas d'installer l'Insider preview, maintenant Vinda installe la nouvelle version une fois par semaine. Il est préférable de télécharger la version stable sur le site de MS. C'est ma curiosité d'enfant qui joueencore à un endroit :)

Raison: