Bibliothèque de classes génériques - bogues, description, questions, caractéristiques d'utilisation et suggestions - page 25

 
Andrey Pogoreltsev:

Pourquoi créer des collections et les mettre dans une kodobase si elles ne sont bonnes que pour les types embarqués) ?

Ils ne sont pas bons non plus pour les structures encastrées.

 
Andrey Pogoreltsev:

Dites-moi, peut-être que je ne comprends pas quelque chose, mais si j'essaie d'utiliser une construction de ce type :

Je reçois une erreur :

Option - les objets sont transmis uniquement par référence ICollection.mqh 14 18

et il y a une pile complète d'erreurs ensuite...

Cela ne fonctionnera pas, par le biais d'un modèle de modèle doivent faire, j'ai également travaillé avec ce problème, voici un exemple de test, il semble fonctionner correctement

classe CData - structure que nous voulons stocker dans la liste

CDataBase - la liste elle-même

#property strict
#include <Arrays\List.mqh>

//+------------------------------------------------------------------+
class CData : public CObject
  {
public:
   int               x;
   double            y;
   datetime          t;
  };
//+------------------------------------------------------------------+
template<typename TDB>class CDataBase
  {
private:
   CList            *mlist;
   TDB              *TDBptr;
public:
   void CDataBase()           { mlist=new CList;                                       }
   void ~CDataBase(void)      { delete mlist;                                          }
   int ArraySize(void)        { return(mlist.Total());                                 }
   TDB *operator[](int index) { return(mlist.GetNodeAtIndex(index));                   }
   void  AddValue (TDB &value){ TDBptr = new TDB; TDBptr  = value; mlist.Add(TDBptr);  }
   string TypeName()          { return(typename(TDB));                                 }
   };
//+------------------------------------------------------------------+
// проверка, запишем  распринтуем значения
void OnStart()
  {

   CDataBase<CData>*data=new CDataBase<CData>;
   CData *my=new CData;

   int i;
   Print("1------------------------------------");
   for(i=0; i<10; i++)
     {
      my.x=i;
      my.y= i*2;
      data.AddValue(my);
      Print(i," : ",data[i].x," , ",data[i].y," / ",my.x," ,",my.y);
     }
   Print("2------------------------------------");
   for(i=0; i<data.ArraySize(); i++)
     {
      Print(i," : ",data[i].x," , ",data[i].y);
     }
   Print(data.TypeName());
   delete my;
   delete data;
  }
//+------------------------------------------------------------------+

Dans OnStart() - créer une liste, y écrire des valeurs, puis les lire. Je l'ai vérifié 2 fois, parce qu'au début, j'ai perdu la visibilité d'une variable locale en écrivant dans la liste - j'écrivais tout bien, mais quand je lisais, j'avais des pointeurs nuls et une erreur.

 
Igor Makanu:

Cela ne fonctionnera pas de cette façon, vous devez utiliser des modèles de gabarits, j'ai été confronté à ce problème aussi, j'ai fait un exemple de test, tout semble fonctionner correctement.

classe CData - structure que nous voulons stocker dans la liste

CDataBase - la liste elle-même

Dans OnStart () - créer une liste, y écrire des valeurs et ensuite les lire. Je le vérifie deux fois, parce que d'abord j'ai perdu quelque part la visibilité d'une variable locale en écrivant dans la liste - j'écrivais bien, mais quand je lisais, j'avais des pointeurs nuls et une erreur.

Votre code fonctionne parce que CData est toujours une classe, pas une structure. Si vous essayez d'utiliser le générateur pour les classes et les structures à la fois, vous aurez des problèmes, notamment avec l'opérateur de suppression. J'en ai été convaincu par mes propres expériences avec ce "générique". Le fait est que cette bibliothèque "générique" n'a pas du tout d'opérateur de suppression et si vous ajoutez une nouvelle classe à une telle "collection", après avoir quitté le programme, il y aura beaucoup d'objets perdus. C'est-à-dire qu'il est évident qu'à l'origine, ce générique n'a été écrit que pour les types primitifs.

 
Vasiliy Sokolov:

Ce code fonctionne pour vous car CData est une classe et non une structure. Si vous essayez d'utiliser les génériques pour les classes et les structures en même temps, vous rencontrerez immédiatement des problèmes, notamment avec l'opérateur delete. J'en ai été convaincu par mes propres expériences avec ce "générique". Le fait est que cette bibliothèque "générique" n'a pas du tout d'opérateur de suppression et si vous ajoutez une nouvelle classe à une telle "collection", après avoir quitté le programme, il y aura beaucoup d'objets perdus. C'est-à-dire que vous pouvez voir qu'à l'origine ce générique a été écrit uniquement pour les types primitifs.

J'ai arrêté d'utiliser les structures dans MQL, la structure n'a pas d'avantages, mais les bugs constants et la perte de temps en travaillant avec les structures qu'ils fourniront - j'ai lu les anciens messages des administrateurs avec des questions sur les structures et ils disaient essentiellement d'utiliser la classe au lieu de la structure - je n'utilise plus du tout les structures maintenant.

SZZ : J'ai trouvé ceci lorsque j'ai arrêté d'utiliser les structureshttps://www.mql5.com/ru/forum/6343/page866#comment_7541747.

Вопросы от начинающих MQL5 MT5 MetaTrader 5
Вопросы от начинающих MQL5 MT5 MetaTrader 5
  • 2018.05.23
  • www.mql5.com
Подскажите пожалуйста, такой показатель тестера в жизни реален? И хороший это или плохой результат за год с депо 3000...
 
Andrey Pogoreltsev:

pourquoi créer des collections et les mettre dans une kodobase si elles ne sont bonnes que pour les types embarqués) ?

Des commodités qui font partie de la norme. Il n'est donc pas nécessaire de tirer - chaque utilisateur en a un.

Je l'utilise depuis longtemps dans une de mes librairies KB.

 
Igor Makanu:

Cela ne fonctionnera pas de cette façon, vous devez utiliser des modèles de gabarits, j'ai été confronté à ce problème aussi, j'ai fait un exemple de test, tout semble fonctionner correctement.

classe CData - la structure que nous voulons stocker dans la liste

CDataBase - la liste elle-même

Dans OnStart () - créer une liste, y écrire des valeurs et ensuite lire, 2 fois je le vérifie, parce qu'au début quelque part j'ai perdu la visibilité d'une variable locale en écrivant dans la liste - j'écrivais tout ok, mais quand je lisais, alors j'avais des pointeurs nuls lus et j'ai eu une erreur

Tout d'abord, vous avez implémenté votre allocateur sur une liste et y avez stocké des pointeurs. En plus de cela, vous avez une fuite lors de la destruction).

Deuxièmement, vous auriez dû utiliser correctement le constructeur de copie au lieu de l'opérateur d'affectation. Mais tout ceci est IMHO)

Et le plus important : les développeurs n'ont qu'à finaliser les génériques, faire des allocateurs à l'intérieur et prendre en charge les objets personnalisés. C++ a déjà tout inventé pour eux) Et nous n'avons pas à inventer les bicyclettes.

 
Andrey Pogoreltsev:

Tout d'abord, vous avez implémenté votre allocateur sur une liste et y avez stocké les pointeurs. Non seulement cela, mais vous avez des fuites sur la destruction)

Comment avez-vous détecté les fuites ?

SZZ : c'est un exemple de test, je devais comprendre comment travailler avec des listes dans MQL, alors j'ai fait des tests.

 
Andrey Pogoreltsev:

Et le plus important : les développeurs devraient simplement terminer les génériques, faire des allocateurs à l'intérieur et supporter les objets personnalisés. C++ a déjà tout inventé pour eux) Et nous n'avons pas à inventer les bicyclettes.

Écrivez-le si c'est aussi simple que ça.

 
Igor Makanu:

comment les fuites ont-elles été détectées ?

ZS : c'est un exemple de test, je devais comprendre comment travailler avec des listes dans MQL, donc j'ai fait des tests.

Vous créez des copies des objets dans AddValue via new, mais vous ne les libérez pas dans destructor, vous effacez juste la liste des pointeurs.

 
TheXpert:

écrire si c'est aussi simple que ça.

Quand j'aurai le temps et le besoin, j'écrirai. Et en général, à titre d'exemple, créer sa propre usine de roulements n'est pas une bonne idée si vous n'avez besoin que d'un seul modèle de roulement).

Raison: