MQL5中的OOP问题 - 页 46

 
Igor Makanu:

这正是我所逃避的,这也是我一开始所做的。

用这种方法--从一个基类继承,"一切都在那里"--一切都可以,但直到我们想尝试做几个类的字段,然后我们想在每个字段类中增加更多的字段,用一个动态数组 的类来钉住这一切。

然后我们会得到,我们不能在基类中实现Save(int hndl)方法本身--这个方法实际上是一个接口,正如上面所讨论的,根本不需要--你可以不用接口来写它

我通常在代码的灵活性方面做出最大的努力--最小的麻烦--结果是解决了一个新的问题,愿我的术语得到原谅)))。


问题是,在实现保存到文件时,你需要制定文件头, 它应该描述不同类型的条目总量。然后你需要制定数据保存的逻辑/顺序,以便正确读取所有内容....。最后的结局是,如果你改变了一个类中的哪怕一个字段

我认为,这种从基类中 "轻松 "继承的做法是很费力的,因为要开发和维护一个小的数据库,不断监测任何类的变化。

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

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

像这样))))

 
Vladimir Simakov:

像这样))))

我理解这一切,但对于 "MQL不是C "这句老话,你只能补充说,依靠按任务划分的结构良好的代码是没有意义的--MQL任务总是高度专业化的,重复使用大型代码往往是无效的。

HH:我认为MQL代码的主要目标是尽可能快,在测试器中使用或在一个tick内执行代码--不损失tick,这一切都很清楚,但也有一些限制--你不能忽视连接中断和PC/终端重启,这都是为了找到最佳状态,而不仅仅是一个漂亮和 结构化的代码。

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

我们初始化矩阵A,然后C

我们首先分配一个新的矩阵B=A,并取消初始化,然后B=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

重点是--你需要把结构包进结构里,然后再包进结构里....。请原谅我的专业术语 ))))


SZY: 解决方案很好,我们应该用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:

有一个办法,和往常一样,解决方案很简单。

初始化矩阵A,然后C

首先指定一个新的矩阵B=A,并取消初始化,然后B=C,取消初始化。


SZY: 解决方案很好,我们需要用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中的OOP问题

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 检查我和你的版本的速度

我稍后会检查一下速度,我正在上课。