Biblioteca de clases genéricas - errores, descripción, preguntas, características de uso y sugerencias - página 25

 
Andrey Pogoreltsev:

¿Por qué crear colecciones y ponerlas en un kodobase si sólo sirven para tipos incrustados)?

Tampoco son buenos para las estructuras empotradas.

 
Andrey Pogoreltsev:

Dígame, tal vez no entiendo algo, pero si trato de usar una construcción de este tipo:

Me da un error:

'Opción' - los objetos se pasan sólo por referencia ICollection.mqh 14 18

y hay una pila completa de errores a continuación...

Esto no va a funcionar, a través de una plantilla de la necesidad de hacer, también he trabajado con este problema, aquí es un ejemplo de prueba, parece que funciona correctamente

class CData - estructura que queremos almacenar en la lista

CDataBase - la propia lista

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

En OnStart() - creamos una lista, escribimos valores en ella, y luego los leemos. Lo compruebo 2 veces, porque al principio en alguna parte perdía la visibilidad de una variable local al escribir en la lista - escribía todo bien, pero al leer, entonces obtenía punteros nulos y un error

 
Igor Makanu:

No funcionará así, tienes que usar plantillas, yo también estaba lidiando con este problema, hice un ejemplo de prueba, todo parece funcionar correctamente

class CData - estructura que queremos almacenar en la lista

CDataBase - la propia lista

En OnStart () - crear una lista, escribir valores en ella y luego leerlos. Lo compruebo dos veces, porque primero he perdido en alguna parte la visibilidad de una variable local al escribir en la lista - estaba escribiendo todo bien, pero cuando estaba leyendo, entonces tenía punteros nulos y un error

Tu código funciona porque CData sigue siendo una clase, no una estructura. Si intentas utilizar el generador para clases y estructuras a la vez, tendrás problemas, especialmente con el operador de borrado. Me convencí de ello a través de mis propios experimentos con este "genérico". La cuestión es que esta librería "genérica" no tiene operador de borrado en absoluto y si añades una nueva clase a dicha "colección", después de salir del programa habrá un montón de objetos perdidos. Es decir, es obvio que originalmente este genérico fue escrito sólo para tipos primitivos.

 
Vasiliy Sokolov:

Este código le sirve porque CData es una clase, no una estructura. Si intentas usar genéricos para clases y estructuras al mismo tiempo, encontrarás inmediatamente problemas, especialmente con el operador de borrado. Me convencí de ello a través de mis propios experimentos con este "genérico". La cuestión es que esta librería "genérica" no tiene operador de borrado en absoluto y si añades una nueva clase a dicha "colección", después de salir del programa habrá un montón de objetos perdidos. Es decir, puedes ver que originalmente este genérico fue escrito sólo para tipos primitivos.

He dejado de usar estructuras en MQL, la estructura no tiene ninguna ventaja, pero los constantes errores y la pérdida de tiempo mientras se trabaja con las estructuras que proporcionarán - leí los antiguos posts de los administradores con preguntas sobre las estructuras y básicamente decían que usara la clase en lugar de la estructura - no uso estructuras en absoluto ahora

SZZ: Encontré esto cuando dejé de usar estructurashttps://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:

¿por qué crear colecciones y ponerlas en un kodobase si sólo sirven para los tipos incrustados)?

Comodidades que vienen de serie. Por lo tanto, no es necesario tirar - cada usuario tiene uno.

Yo utilizo esto en una de mis librerías KB por mucho tiempo.

 
Igor Makanu:

No funcionará así, tienes que usar plantillas, yo también estaba lidiando con este problema, hice un ejemplo de prueba, todo parece funcionar correctamente

class CData - la estructura que queremos almacenar en la lista

CDataBase - la propia lista

En OnStart () - crear una lista, escribir valores en ella y luego leer, 2 veces lo compruebo, porque al principio en alguna parte perdía la visibilidad de una variable local al escribir en la lista - escribía todo bien, pero cuando leía, entonces tenía punteros nulos leídos y obtenía un error

Bueno, en primer lugar, implementaste tu asignador sobre una lista y almacenaste punteros allí. No sólo eso, tiene una fuga al destruir).

En segundo lugar, deberías haber utilizado correctamente el constructor de copia en lugar del operador de asignación. Pero todo esto es IMHO)

Y lo más importante: los desarrolladores sólo tienen que finalizar los genéricos, hacer asignadores en su interior y admitir objetos personalizados. C++ ya lo ha inventado todo para ellos) Y no tenemos que inventar las bicicletas.

 
Andrey Pogoreltsev:

Bueno en primer lugar has implementado tu asignador sobre una lista y almacenas los punteros allí. Y no sólo eso, sino que tienes fugas en la destrucción)

¿Cómo ha detectado las fugas?

SZZ: es un ejemplo de prueba, tenía que averiguar cómo trabajar con listas en MQL, así que hice pruebas.

 
Andrey Pogoreltsev:

Y lo más importante: los desarrolladores deberían acabar con los genéricos, hacer asignadores en su interior y dar soporte a los objetos personalizados. C++ ya lo ha inventado todo para ellos) Y no tenemos que inventar las bicicletas.

Escríbelo si es así de sencillo.

 
Igor Makanu:

¿cómo se detectaron las fugas?

ZS: es un ejemplo de prueba, tenía que averiguar cómo trabajar con listas en MQL, así que hice pruebas.

Creas copias de objetos en AddValue a través de new, pero no los liberas en el destructor, sólo borras la lista de punteros.

 
TheXpert:

escribir si es así de sencillo.

Cuando tenga el tiempo y la necesidad, escribiré. Y en general, como ejemplo, montar tu propia fábrica de rodamientos no es una buena idea si sólo necesitas un modelo de rodamiento)