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

 
Igor Makanu:

именно от этого я и ушел, а сначала так и делал

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

и получим, что сам метод Save(int hndl)- мы не можем реализовать в базовом классе, этот метод будет по сути интерфейсом, который, как обсуждали, да и не нужен вовсе - без интерфейсов тож можно же писать

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


а проблема будет, что при реализации сохранения в файл нужно будет разработать заголовок файла, в котором нужно будет описать общее количество разнотипных записей, потом нужно будет не потерять логику/порядок сохранения данных, чтобы правильно все прочитать.... и финал будет, если изменили хоть одно поле в одном классе

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

public:
 void CBase::Save(...){
    SaveHeard(...);
    _Save(...)}
virtual void SaveHeard(...){...}

protected:
   void _Save(...){
       CBase::_Save(...);
       ...}

Как-то так))))

 
Vladimir Simakov:

Как-то так))))

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

ЗЫ: имхо основная задача кода MQL  быть максимально быстрым, чтобы использовать в тестере или выполнять код за один тик - без пропуска тиков, вроде все это понятно, но есть и ограничения - нельзя не учитывать ситуации обрыва связи и перезагрузки ПК/терминала, и вот во всем этом нужно найти оптимум, а не просто красивый и структурированный код 

 
Igor Makanu:

2. есть ли хак, чтобы описать operator= , и в нем использовать родной оператор копирования? .... т.е. некий способ вызвать  ::=

способ есть, и как обычно решение простое:

struct SMatrix
{
   struct SMATRIX{
   SMATRIX(){}
   struct SRow{int COL[];};
   SRow ROW[];
   };
   SMATRIX MATRIX;
   SMatrix(){}
   SMatrix(const int rows,const int cols){ this.Resize(rows,cols); }
   void Resize(const int rows,const int cols){ ArrayResize(this.MATRIX.ROW,rows); for(int i=0;i<rows; i++){ ArrayResize(this.MATRIX.ROW[i].COL,cols); }}
   void Free() { for(int i=0;i<ArraySize(this.MATRIX.ROW[i].COL); i++){ ArrayFree(this.MATRIX.ROW[i].COL); } ArrayFree(this.MATRIX.ROW);}
   int RowCount()const { return(ArraySize(this.MATRIX.ROW)); }
   int ColCount()const { if(this.RowCount()>0) return(ArraySize(this.MATRIX.ROW[0].COL)); else return(0); }
   void operator=(const SMatrix &v) { this.Resize(v.RowCount(),v.ColCount()); this.MATRIX = v.MATRIX;}

};

//+------------------------------------------------------------------+
void OnStart()
{
   SMatrix A(2, 5);
   int count = 0;
   for(int i = 0; i < A.RowCount(); i++)
      for(int j = 0; j < A.ColCount(); j++)
         A.MATRIX.ROW[i].COL[j] = count++;
   
   SMatrix C(5, 2);
   count = 100;
   for(int i = 0; i < C.RowCount(); i++)
      for(int j = 0; j < C.ColCount(); j++)
         C.MATRIX.ROW[i].COL[j] = count++;

   
   SMatrix B = A;
   for(int i = 0; i < B.RowCount(); i++)
      ArrayPrint(B.MATRIX.ROW[i].COL);
   
   B = C;
   for(int i = 0; i < B.RowCount(); i++)
      ArrayPrint(B.MATRIX.ROW[i].COL);
   
}

инициализируем матрицу А, затем C

присваиваем сначала новую матрицу  В = А и распринтовали , затем В=С и распринтовали 

2020.04.21 00:35:50.559 tst (EURUSD,H1) 0 1 2 3 4

2020.04.21 00:35:50.559 tst (EURUSD,H1) 5 6 7 8 9

2020.04.21 00:35:50.560 tst (EURUSD,H1) 100 101

2020.04.21 00:35:50.560 tst (EURUSD,H1) 102 103

2020.04.21 00:35:50.560 tst (EURUSD,H1) 104 105

2020.04.21 00:35:50.560 tst (EURUSD,H1) 106 107

2020.04.21 00:35:50.560 tst (EURUSD,H1) 108 109

суть - нужно обернуть структуру в структуру и еще раз в структуру.... прошу прощения за мой технический термин ))))


ЗЫ: решение годное, нужно методы RowCount() и ColCount() на поля структуры RowCount и ColCount заменить, чтобы меньше вызовов было ... но в целом все работает как и хотелось

 
Ты серьёзно? 
 
Алексей Тарабанов:
Ты серьёзно? 

А что тут такого, человек с 2012 года занимается решением данной задачи, не мешайте ему, ему виднее.

 
Sergey Dzyublik:

А что тут такого, человек с 2012 года занимается решением данной задачи, не мешайте ему, ему виднее.

плоско мыслишь

задача знать технические возможности языка MQL, чтобы такой пример https://docs.microsoft.com/en-us/archive/msdn-magazine/2018/april/test-run-understanding-lstm-cells-using-csharp

можно было портировать "в лоб" - сейчас эта задача решена, портирование всех функций примера один в один с одним допущением:  float[][] result --> SMatrix result

 
Igor Makanu:

способ есть, и как обычно решение простое:

инициализируем матрицу А, затем C

присваиваем сначала новую матрицу  В = А и распринтовали , затем В=С и распринтовали 


ЗЫ: решение годное, нужно методы RowCount() и ColCount() на поля структуры RowCount и ColCount заменить, чтобы меньше вызовов было ... но в целом все работает как и хотелось

К сожалению, не всё так радостно, как хотелось бы.  В MQL есть давний баг с копированием массивов дефолтным оператором копирования.  Происходит лишь ArrayCopy элементов из одного массива в другой. А размер итогового массива не синхронизируется с источником (не усекается).  Т.е. если допустим было  A(10),  B(20),  то после B=A у вас будет также B(20), т.е. половина элементов заместится элементами из A, остальные останутся прежними.   Это конечно совсем не то, что ждёшь от оператора=.   Поэтому для массивов придётся прописывать свой оператор.

Я, признаться, думал что этот баг уже пофиксен. Но проверил - воз и ныне там.

 
Alexey Navoykov:

К сожалению, не всё так радостно, как хотелось бы.  В MQL есть давний баг с копированием массивов дефолтным оператором копирования.  Происходит лишь ArrayCopy элементов из одного массива в другой. А размер итогового массива не синхронизируется с источником (не усекается).  Т.е. если допустим было  A(10),  B(20),  то после B=A у вас будет также B(20), т.е. половина элементов заместится элементами из A, остальные останутся прежними.   Это конечно совсем не то, что ждёшь от оператора=.   Поэтому для массивов придётся прописывать свой оператор.

Я, признаться, думал что этот баг уже пофиксен. Но проверил - воз и ныне там.

О баге недавно вспоминали:

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Вопросы по ООП в MQL5

Sergey Dzyublik, 2020.04.18 17:48

Тогда, согласно вашей терминологии, вызов дефолтного оператора присвоения может дать "неполный тип данных".
Баг от 2019.05.03 так и не был исправен: https://www.mql5.com/ru/forum/1111/page2451#comment_11556395


Приведенная строка по идеи должна обходить баг:

struct SMatrix
{
   struct SMATRIX{
   SMATRIX(){}
   struct SRow{int COL[];};
   SRow ROW[];
   };
   SMATRIX MATRIX;
   SMatrix(){}
   SMatrix(const int rows,const int cols){ this.Resize(rows,cols); }
   void Resize(const int rows,const int cols){ ArrayResize(this.MATRIX.ROW,rows); for(int i=0;i<rows; i++){ ArrayResize(this.MATRIX.ROW[i].COL,cols); }}
   void Free() { for(int i=0;i<ArraySize(this.MATRIX.ROW[i].COL); i++){ ArrayFree(this.MATRIX.ROW[i].COL); } ArrayFree(this.MATRIX.ROW);}
   int RowCount()const { return(ArraySize(this.MATRIX.ROW)); }
   int ColCount()const { if(this.RowCount()>0) return(ArraySize(this.MATRIX.ROW[0].COL)); else return(0); }
   void operator=(const SMatrix &v) { this.Resize(v.RowCount(),v.ColCount()); this.MATRIX = v.MATRIX;}

};
 
Sergey Dzyublik:

Приведенная строка по идеи должна обходить баг:

А, ну да, что-то я сразу не заметил...  Но тогда можно было и ArrayCopy сразу написать.  На кой тогда вообще нужна эта прокладка SMATRIX ?..

 
Alexey Navoykov:

А, ну да, что-то я сразу не заметил...  Но тогда можно было и ArrayCopy сразу написать.  На кой тогда вообще нужна эта прокладка SMATRIX ?..

разработчики МТ всегда пишут, что использование встроенных механизмов компилятора будет быстрее вызова даже штатных функций

если есть время и интерес, проверьте скорость моего варианта и своего с ArrayCopy 

я чуть позже проверю скорость , сейчас ПК уроками занят