Preguntas sobre POO en MQL5 - página 16

 
Dmitry Fedoseev:

Labiblioteca estándar asume que los controles se crean en un formulario. Se supone que no funcionan en absoluto, sin más. Al menos, así era antes.

Tendré que probar las últimas versiones de la serie GUI de Kajarski. Lo rápido que le funciona. Y luego volver a escribir a los desarrolladores para que retoquen su idea.
 
Vasiliy Pushkaryov:
Tendré que probar la última versión de la serie de artículos de Kajarsky sobre GUI. Lo rápido que le funciona. Y luego, una vez más, escribir a los desarrolladores para que retoquen su idea.

¡todos caminan en el mismo círculo! ))) - Fue a partir de esta serie de artículos sobre interfaces gráficas que empecé a estudiar las capacidades de MQL .... - La experiencia no fue buena, algunos de los ejemplos de los artículos ya no compilan, el autor se mantiene en contacto, pero el tamaño de la librería es muy grande, no he empezado a utilizarla, aunque puede que lo consiga.

imho - o estudias C# durante una semana - tienes un montón de ejemplos en la web y el diseñador de formularios en VS es el mismo que en Delphi (escribí antes en Delphi), o usas SB de todos modos - al menos tiene apoyo de los desarrolladores

 
Igor Makanu:

¡todos caminan en el mismo círculo! ))) - Fue a partir de esta serie de artículos sobre interfaces gráficas que empecé a estudiar las capacidades de MQL .... - La experiencia no fue buena, algunos de los ejemplos de los artículos ya no compilan, el autor se mantiene en contacto, pero el tamaño de la librería es muy grande, no he empezado a utilizarla, aunque puede que lo consiga.

imho, o aprende C# durante una semana - tienes un montón de ejemplos en la web y el diseñador de formularios en VS es el mismo que en Delphi (en Delphi escribí antes), o usa SB igualmente - al menos tiene apoyo de los desarrolladores

Lamento escuchar que la biblioteca ya está siendo envuelta. Lo probé hace un año más o menos, me gustó el aspecto del panel. Incluso lo retoqué para MT4 y lo probé (debido a las diferencias en Canvas tampoco compiló de inmediato), pero luego, debido a la dificultad de portarlo para mi tarea, tomé SB. Pensé que volvería a los GUIs más tarde.

No creo que pueda dominar C# en una semana. Pero debo ponerme una meta, además ya hay soporte nativo para las bibliotecas .NET. Aquí ha sugerido cómo se puede utilizar para su tarea particular.

 
Vladimir Simakov:

Y en el segundo caso es necesario

void  AddValue (T &value)  { Tptr  = value; mlist.Add(Tptr);       }

Por alguna razón no funcionó con tu versión, tal vez me equivoqué de nuevo )) ,

Quiero guardar datos en una lista sin punteros intermedios, funciona así y sin fugas de memoria:

#property strict
#include <Arrays\List.mqh>
//+------------------------------------------------------------------+
template<typename T>class CDataBase
  {
private:
   CList            *mlist;
public:
   void CDataBase()           { mlist=new CList;                                    }
   void ~CDataBase(void)      { delete mlist;                                       }
   int ArraySize(void)        { return(mlist.Total());                              }
   T operator[](int index)    { return(mlist.GetNodeAtIndex(index));                }
   void  AddValue (T value)   { mlist.Add(value);                                   }
   void  Delete(int pos)      { mlist.Delete(pos);                                  }
   string TypeName()          { return(typename(T));                                }
  };

//+------------------------------------------------------------------+
class CData : public CObject
  {
public:
   int               x;
   double            y;
                     CData(){};
                     CData(int ival,double dval){x=ival;y=dval;}
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnStart()
  {
   CDataBase<CData*>*data=new CDataBase<CData*>;
   int i;
   for(i=0; i<5; i++) data.AddValue(new CData(i,i*2.0));
   Print("Тип БД : ", data.TypeName()," б чтение данных :");
   for(i=0; i<data.ArraySize(); i++) Print(i," : ",data[i].x," , ",data[i].y);
   Print("Удалил № 3");
   data.Delete(3);
   for(i=0; i<data.ArraySize(); i++) Print(i," : ",data[i].x," , ",data[i].y);
   delete data;
  }
//+------------------------------------------------------------------+

esto es sólo el principio de mi idea

Quiero implementar en mi plantilla la escritura y la lectura en un archivo binario (aunque podría hacerlo en un archivo de texto, no importa). No tengo ni idea de cómo escribir CData en un archivo usando una plantilla de clase campo - ¡pero realmente quiero hacerlo!

 
Igor Makanu:

Quiero implementar en mi plantilla la escritura y la lectura en un archivo binario (aunque es posible escribir en un archivo de texto - no es importante), no sé cómo escribir los campos CData en un archivo usando la plantilla - ¡pero realmente quiero hacerlo!)

#property strict
#include <Arrays\List.mqh>
//+------------------------------------------------------------------+
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); }
};

template <typename T>
class CList2 : public CList
{
public:  
  virtual CObject  *CreateElement(void) { return(new T); }
};

template<typename T>class CDataBase
  {
private:
   CList2<T>            *mlist;
public:
   void CDataBase()           { mlist=new CList2<T>;                                    }
   void ~CDataBase(void)      { delete mlist;                                       }
   int ArraySize(void)        { return(mlist.Total());                              }
   T* operator[](int index)    { return(mlist.GetNodeAtIndex(index));                }
   void  AddValue (T* value)   { mlist.Add(value);                                   }
   void  Delete(int pos)      { mlist.Delete(pos);                                  }
   string TypeName()          { return(typename(T));                                }
  bool Save( const string FileName ) const { const FILE File(FileName, FILE_WRITE | FILE_BIN); return(this.mlist.Save(File.handle)); }
  bool Load( const string FileName ) { const FILE File(FileName, FILE_READ | FILE_BIN); return(this.mlist.Load(File.handle)); }

  };

//+------------------------------------------------------------------+
class CData : public CObject
  {
public:
   int               x;
   double            y;
                     CData(){};
                     CData(int ival,double dval){x=ival;y=dval;}
   virtual bool      Save( const int file_handle ) { return(::FileWriteInteger(file_handle, this.x) && ::FileWriteDouble(file_handle, this.y)); }
   virtual bool      Load( const int file_handle )
   {
     ::ResetLastError();
     
     this.x = ::FileReadInteger(file_handle);
     this.y = ::FileReadDouble(file_handle);
     
     return(!::GetLastError());
   }
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnStart()
  {
   CDataBase<CData>*data=new CDataBase<CData>;
   int i;
   for(i=0; i<5; i++) data.AddValue(new CData(i,i*2.0));
   Print("Тип БД : ", data.TypeName()," б чтение данных :");
   for(i=0; i<data.ArraySize(); i++) Print(i," : ",data[i].x," , ",data[i].y);
   
   data.Save("Data.bin");
   delete data;

   CDataBase<CData> data2;   
   data2.Load("Data.bin");
   Print("Тип БД : ", data2.TypeName()," б чтение данных :");
   for(i=0; i<data2.ArraySize(); i++) Print(i," : ",data2[i].x," , ",data2[i].y);
  }
//+------------------------------------------------------------------+

Nunca he trabajado con CList y CObject, pero las fuentes son sencillas (por cierto, hay un método virtual Save sin modificador const por alguna razón), así que funcionó a la primera.


SZY Es más fácil escribir así.

template<typename T>class CDataBase
  {
private:
   CList2<T>            mlist; // Объект, не указатель

Entonces no necesitarás el constructor/destructor. Tiene sentido utilizar new/delete donde es realmente útil. De lo contrario, puede hacer lo mismo que con FILE arriba.

 
fxsaber:

Nunca he trabajado con CList y CObject, pero el código fuente es sencillo, así que funcionó de inmediato.

¡Oh! ¡Tienes una respuesta tan rápida! - ¡GRACIAS! - Tendré algo que hacer por la noche.

Yo también fuente CList y CObject, leer, no ver los problemas, pero las pruebas tienen que llevar a cabo

ZS: aquí en general lo que quiero conseguir... una especie de lista universal:

1. en el que las estructuras de clase se pueden añadir inmediatamente en la creación (implementado - comprobado mi ejemplo data.AddValue(new CData(i,i*2.0)) - OK)

2. en el que se puede escribir y leer desde el archivo "DB" (comenzó a escribir, hasta ahora el constructor de la plantilla es

1. void CDataBase()           { mlist=new CList; m_file_handle=INVALID_HANDLE;         }
2. void CDataBase(int BaseID) { mlist=new CList;m_id=BaseID;m_file_handle=fileopen();  }

funcionan sin escribir/leer en el archivo #1 y #2 leen la base de datos cuando se crea la CDataBase desde el disco y escriben en el disco cuando se llama al destructor

....

ZS:

¿qué sentido tiene todo esto? -Solo escribo EAs según un esquema estándar - un mago y todas las manipulaciones con órdenes a través de la búsqueda de una orden con un mago, si el TS no es "indicador 101" sino más complicado, normalmente 2 magos son suficientes, pero si el TS está monitoreando 80 órdenes pendientes (10 rejillas de órdenes, las rejillas se reabren y ... Para ser honesto es absurdo pero me lo he encontrado por segunda vez), entonces empiezo a usar varios trucos - conduciendo 80 órdenes en 80 magos generados ))) - Salí de ella, pero no me gusta del todo

Me gustaría por fin crear una pequeña base de datos en la que poder escribir datos sobre las órdenes (todo lo demás) y, lo más importante, no prestar atención a la base de datos en sí misma - acceder como alos elementos de la matriz, leer y escribir en un archivo cuando el EA se abre o se cierra

y así sucesivamente ))))


fxsaber:

SZZ Es más fácil escribir

Entonces no necesitas un constructor/destructor. El nuevo/borrado debe usarse donde sea realmente útil. Para el resto, puedes hacer lo mismo que hiciste con FILE más arriba.

Gracias, pero todavía tengo que pensarlo... o mejor dicho, quiero hacerlo de tal manera que no tenga que pensarlo después))) - cuando OnInit() crea la base de datos, lee el archivo y DeInit() mata la base de datos, guarda el archivo y si se le pasó borrar en DeInit(), la terminal hará una nota al respecto en el diario... En mi opinión, excluye los errores al trabajar con la base de datos... en general, si lo hago, veré lo conveniente que es

 
fxsaber:
virtual bool      Load( const int file_handle )
   {
     ::ResetLastError();
     

si no te importa, por qué usar " :: "https://www.mql5.com/ru/docs/basis/operations/other

 
Igor Makanu:

si no le importa, ¿por qué utilizamos aquí " :: "?

Si no, tengo que comprobar que las clases padre no tienen un método con el mismo nombre. Y aunque no lo haya, si alguien lo añade, el código seguirá funcionando.

Por la misma razón, siempre utilizo esto para que no haya ambigüedad y sea más fácil de leer.


ZZY Pero en algunas situaciones raras :: y esto le quita flexibilidad. Hay sutilezas similares sobre cuándo es mejor escribir el cuerpo del método dentro de la clase y cuándo fuera. Recuerdo haberme encontrado con todo esto, pero no voy a dar ejemplos.

 
fxsaber:

Si no, tengo que comprobar que las clases padre no tienen un método con el mismo nombre. Y aunque no lo haya, si alguien lo añade, el código seguirá funcionando.

Por la misma razón siempre uso esto para la claridad y la legibilidad.

Sí, es realmente práctico y evita los errores, lo tendré en cuenta

Gracias.

 
Igor Makanu:

4. si la bandera de escritura del archivo m_fsave está activa, entonces cada vez que llamamos al método AddValue() - añadimos más datos al archivo

Mira el formato de registro de CList. Lo estás ignorando.

Razón de la queja: