Questions sur la POO dans MQL5 - page 90

 
Igor Makanu:

si dans mon exemple :

copier les valeurs asc et bid dans la méthode onTick() et utiliser _Ask, _Bid (transaction virtuelle) dans le reste des méthodes

Est-ce que ce sera comme travailler avec des variables globales ?

ZS : comme option, je peux bien sûr passer par référence &tick à toutes les méthodes, mais je me demande encore une fois ce qui est le plus efficace.

Si ce sujet est toujours d'actualité, je tiens à souligner que l'option consistant à conserver les champs est à la fois moins efficace et moins correcte d'un point de vue conceptuel. En principe, les deux concepts sont presque toujours corrélés.
Un code propre (sans effets secondaires) est toujours mieux optimisé par le compilateur, et plus facile à comprendre.
Si votre objet est censé changer d'état sous l'influence de données d'entrée, il ne doit pas stocker ces données d'entrée (sauf à des fins de mise en cache).
Vous devez séparer les mouches des escalopes.

 

On m'a posé une question sur deux façons d 'initialiser des variables dans une classe. Celui-là :

class CA{
   protected:
      int val;
   public:
      CA(){
         val=0;
      }      
};

Et celui-là :

class CA{
   protected:
      int val;
   public:
      CA():val(0){
      }      
};

J'ai demandé quel était l'avantage de la deuxième méthode et on m'a répondu qu'elle permettait d'initialiser les membres statiques. Mais les membres statiques ne sont pas initialisés de cette façon.

La question est donc la même : quelle est la différence de principe et quel est l'avantage de la seconde voie ?

 

Citation

Хочется закончить свою песнь важными словами. Любые описанные механизмы, принципы и паттерны, как и ООП в целом не стоит применять там, где это бессмысленно или может навредить. Это ведет к появлению статей со странными заголовками типа «Наследование — причина преждевременного старения» или «Синглтон может приводить к онкологическим заболеваниям».
 
Dmitry Fedoseev:

On m'a posé une question sur deux façons d 'initialiser des variables dans une classe. En voici une comme ça :

https://www.mql5.com/ru/forum/85652/page45#comment_15975127

Dmitry Fedoseev:

J'ai demandé quel était l'avantage de la deuxième méthode et on m'a répondu que les membres statiques pouvaient être initialisés par elle. Mais les membres statiques ne sont pas initialisés de cette façon.

Il s'agit de champs constants , et non statiques.

class CA
{
protected:
   const int         val;
   static int        static_val;
public:
                     CA(): val(0) { }
};
static int CA::static_val = 12345;
Dmitry Fedoseev:

La question est donc toujours la même : quelle est la différence de principe et quel est l'avantage de la seconde voie ?

Si l'on écarte l'argument "c'est mal vu", alors on utilisera ce qui est le plus pratique, à mon avis.

 
Oui, c'est ça, constant, confus)
 

Je vais relancer le sujet, j'ai supprimé le post précédent, je pensais avoir trouvé la solution moi-même.....


Voici le code :

class CSetting  
{
public:
   enum T            {T1, T2, T3, T4, T5, T6, T7, T8};
   enum D            {D1, D2, D3, D4, D5, D6, D7, D8};
   enum V            {V1, V2, V3, v4};
private:
   int               param1, param2;
   T                 t;
   D                 d;
   V                 v;
public:
                     CSetting(const int in_param1,const int in_param2,const T in_t,const D in_d,const V in_v);
  };
//+------------------------------------------------------------------+
CSetting::CSetting(const int in_param1,const int in_param2,const T in_t,const D in_d,const V in_v)
   : param1(in_param1),
     param2(in_param2),
     t(in_t),
     d(in_d),
     v(in_v)
  {}

//--- input parameters
input int              Input_p1 = 1;   // p1 = -1000 ... +1000
input int              Input_p2 = 2;   // p2 = -1000 ... +1000
input CSetting::T      Input_T = CSetting::T::T1;
input CSetting::D      Input_D = CSetting::D::D1;
input CSetting::V      Input_V = CSetting::V::V1;

Je veux que 3 enums et 2 ints de la section privée de CSetting soient remplis avec un int dans lequel je vais stocker ces données bit par bit, j'ai esquissé le code :

class CSetting
  {
public:
   enum T            {T1, T2, T3, T4, T5, T6, T7, T8};
   enum D            {D1, D2, D3, D4, D5, D6, D7, D8};
   enum V            {V1, V2, V3, v4};
private:
   int               param1, param2;
   T                 t;
   D                 d;
   V                 v;
public:
                     CSetting(const uint data);
  };
//+------------------------------------------------------------------+
CSetting::CSetting(const uint data)
{
   v = (V)(data & 0x3);
   d = (D)((data >> 2) & 0x7);
   t = (T)((data >> 5) & 0x7);
   uint tmp = ((data >> 8) & 0xFFF);
   param2 = (tmp & 0x800) == 0x800 ? -(int)(tmp & 0x7FF) : (int)(tmp & 0x7FF);
   tmp = data >> 20;
   param1 = (tmp & 0x800) == 0x800 ? -(int)(tmp & 0x7FF) : (int)(tmp & 0x7FF);
}
//+------------------------------------------------------------------+
//--- input parameters
input int DATA         = 0xFFFFFFFF;

en théorie, cela devrait fonctionner, je prends les 2 + 3 +3 bits inférieurs des données de l'enum , et les 24 bits restants de l'int pour remplir param1 et param2, en gardant le 12ème bit comme caractère du nombre.


Comment puis-je vérifier s'il y a une erreur ? )))

ou je serais reconnaissant à quelqu'un d'autre de me donner une idée sur la façon de sauvegarder ces données dans un fichier int.

 
Alternativement : t+d*10+v*100
 
Igor Makanu:

comment vérifier s'il y a des erreurs ? )))

La méthode habituelle - l'emballer, le déballer, vérifier s'il est identique. Vérifier de préférence tous les cas limites.
 
Dmitry Fedoseev:
ou t+d*10+v*100

cela ne fonctionnera pas,

vous devez soit décaler le bit par bit, soit multiplier/splitter par 2, ce qui équivaut à décaler

TheXpert:
bien, comme d'habitude - l'emballer, le déballer, vérifier l'identité. vérifier de préférence tous les cas limites.

Alors, oui... logiquement

mais je n'avais pas l'intention de faire de l'empaquetage - je diminue le nombre de variables d'entrée pour l'optimiseur et j'ai besoin de plusieurs passages de GA au-dessus d'elles, de sorte que GA ne converge pas rapidement.


Les cas limites ont déjà été vérifiés, mais par expérience.... les insectes sont si ingénieux ! !! )))

HH : Je peux bien sûr réinitialiser la boucle de 0...MAX_UINT dans un fichier et la regarder visuellement, mais ce n'est pas la meilleure option, à mon avis.

 
Igor Makanu:

ça ne marchera pas,

...

Pourquoi ça ne marcherait pas ? Trois énumérations, dont aucune ne dépasse 10. Arithmétique de deuxième année d'école primaire.