Вопросы по ООП в MQL5 - страница 16

 
Dmitry Fedoseev:

Стандартная библиотека подразумевает, что контролы создаются на форме. Просто так они, вроде как, и вообще не должны работать. По крайней мере так было когда-то раньше.

Надо будет попробовать последние версии Кажарского из цикла статей про графические интерфейсы. Насколько быстро у него работает. И тогда еще раз писать разработчикам, чтобы подправили свое детище.
 
Vasiliy Pushkaryov:
Надо будет попробовать последние версии Кажарского из цикла статей про графические интерфейсы. Насколько быстро у него работает. И тогда еще раз писать разработчикам, чтобы подправили свое детище.

все ходят по одному кругу! ))) - именно из этого цикла статей про графические интерфейсы я и начал изучение возможностей MQL .... - опыт неудачный, часть примеров из статей уже не компилируются, автор выходит на связь, но обьем библиотеки очень большой, я не стал этой библиотекой пользоваться , хотя возможно у Вас получится

имхо или в течении недели изучить C# - примеров в сети уйма и дизайнер форм в VS  такой же как в Делфи (на Делфи я писал ранее), или все таки использовать СБ - там хоть поддержка есть от разработчиков

 
Igor Makanu:

все ходят по одному кругу! ))) - именно из этого цикла статей про графические интерфейсы я и начал изучение возможностей MQL .... - опыт неудачный, часть примеров из статей уже не компилируются, автор выходит на связь, но обьем библиотеки очень большой, я не стал этой библиотекой пользоваться , хотя возможно у Вас получится

имхо или в течении недели изучить C# - примеров в сети уйма и дизайнер форм в VS  такой же как в Делфи (на Делфи я писал ранее), или все таки использовать СБ - там хоть поддержка есть от разработчиков

Жаль слышать, что та библиотека уже заворачивается. Я год или полтора назад ее пробовал, внешний вид панели мне понравился. Даже под МТ4 ее подправил и попробовал (из-за отличий в Canvas что-то сходу тоже не компилировалось) но потом, да, из-за сложности портирования под свою задачу, взял СБ. Подумал, что позже вернусь к графическим интерфейсам.

С# я вряд ли за неделю освою. Но поставить себе эту цель нужно, тем более уже есть нативная поддержка .NET библиотек. Вот и Вы подсказали, как его можно для своей конкретной задачи использовать.

 
Vladimir Simakov:

А во втором случае надо

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

почему то не получилось с Вашим вариантом, может быть опять я накосячил )) ,

но получилось в итоге, что хотел - хочу без промежуточных указателей сразу в список сохранять данные, вот так работает и без утечек памяти:

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

тут как бы только начало моей идеи

хочу в свой шаблон запись и чтение в бинарный файл (хотя можно и в текстовый файл - не принципиально)  реализовать, пока не соображу как можно с помощью шаблона поля class CData в файл записать - но очень хочется!  ;)

 
Igor Makanu:

хочу в свой шаблон запись и чтение в бинарный файл (хотя можно и в текстовый файл - не принципиально)  реализовать, пока не соображу как можно с помощью шаблона поля class CData в файл записать - но очень хочется!  ;)

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

Никогда не работал с CList и CObject, но исходники простые (кстати, там виртуальный метод Save по какой-то причине без модификатора const), поэтому сразу получилось.


ЗЫ Проще так написать

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

Тогда конструктор/деструктор не понадобятся. new/delete все же логично использовать там, где это, действительно, полезно. В остальном можно поступать так, как с FILE выше.

 
fxsaber:

Никогда не работал с CList и CObject, но исходники простые, поэтому сразу получилось.

О! так быстро ответ получил! - БЛАГОДАРЮ! - будет чем ночью заняться.

я тоже исходники CList и CObject, читаю, проблем не наблюдаю, но тесты нужно проводить

ЗЫ: тут в общем что хочу получить... ну вроде как универсальный список:

1. в который можно добавлять структуры классы сразу при создании  (реализовано - проверял мой пример data.AddValue(new CData(i,i*2.0)) - ОК)

2. в котором можно писать в файл и читать из файла "БД" (начал писать, пока конструктор шаблона вижу так

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();  }

 работаем без записи/чтения в файл №1 и №2 читаем БД при создании CDataBase с диска и запись на диск при вызове деструктора 

....

ЗЫ:

ну и зачем все это? -пишу советников по стандартной схеме - магик и все манипуляции с ордерами через поиск ордера по магику, если ТС не по "101 индикатору", а сложнее то обычно 2 магика хватает, НО если ТС со отслеживанием 80 отложенных ордеров (10 сеток ордеров, сетки переоткрываются и ... если честно абсурдная ТС, но уже столкнулся с таким второй раз), то тут начинаются различного рода ухищрения - веду 80 ордеров по 80 сгенерированным магикам ))) - выкрутился, но не нравится мне все это

вот и хочу в итоге сделать маленькую БД в которую можно писать данные по ордерам (да все что угодно) и главное чтобы на саму БД вообще не обращать внимания - доступ как к элементам массива, чтение и запись в файл при запуске или выключении советника

кактотак )))


fxsaber:

ЗЫ Проще так написать

Тогда конструктор/деструктор не понадобятся. new/delete все же логично использовать там, где это, действительно, полезно. В остальном можно поступать так, как с FILE выше.

Спасибо, но тут еще подумать нужно...вернее хочется сделать так чтобы не думать в дальнейшем ))) - в OnInit()  создали БД, она прочитала файл, в DeInit() - убили БД, она записала файл, причем если проморгал delete в DeInit() , то терминал сам об этом сделает запись в журнал... по моему это исключает ошибки при работе с БД... в общем если сделаю там видно будет как удобно

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

если не затруднит, то зачем тут используем " ::    "   https://www.mql5.com/ru/docs/basis/operations/other  

 
Igor Makanu:

если не затруднит, то зачем тут используем " ::    "

Иначе мне придется проверять, что в родительских классах нет одноименного метода. А даже если и нет, то если кто-то его добавит, код все равно останется рабочим.

По этой же причине использую всегда this для однозначности и читабельности.


ЗЫ Но в некоторых редких ситуациях :: и this лишают гибкости. Тут похожие тонкости на то, когда лучше писать тело метода внутри класса, а когда - снаружи. Помню, что со всем этим сталкивался, но примеров не приведу.

 
fxsaber:

Иначе мне придется проверять, что в родительских классах нет одноименного метода. А даже если и нет, то если кто-то его добавит, код все равно останется рабочим.

По этой же причине использую всегда this для однозначности и читабельности.

да это действительно практично и исключает появление багов, возьму на вооружение

Спасибо! 

 
Igor Makanu:

4. если флаг записи в файл m_fsave активен, то каждый раз вызывая метод AddValue() - производим дозапись в файл

Посмотрите формат записи CList. Вы его игнорируете.

Причина обращения: