MQL5におけるOOPに関する質問 - ページ 46

 
Igor Makanu:

それこそ、私が最初に逃げ出したのは、それだったのです。

このアプローチでは、「すべてのものがある」ベースクラスを継承することで、すべてがうまくいきますが、いくつかのクラスフィールドを作ってみて、それぞれのフィールドクラスでさらにフィールドを追加し、クラスの動的配列で すべてに釘を打つまでは

で、Save(int hndl) メソッド自体を基底クラスで実装できないことがわかります。このメソッドは実際にはインターフェースになりますが、これは上で述べたように全く必要ありません。インターフェースなしで書くことができるのです

私は通常、コードの柔軟性に最大限の努力を払います - 最小限の手間で - 結果的に新しい問題が解決されます。)


問題は、ファイルへの保存を実装する際に、ファイルヘッダに 様々な種類のエントリの合計量を記述し、すべてを正しく読み取るために、データ保存の論理/順序を失わないようにする必要があることです....そしてフィナーレは、1つのクラスのフィールドを1つでも変更すると

ベースクラスから「簡単に」継承することは、小さなデータベースの開発と維持、どのクラスの変更も常に監視することになるのです。

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

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

こんな感じ))))

 
Vladimir Simakov:

こんな感じ))))

しかし、「MQLはC言語ではない」という古い言葉に、「タスクごとによく構造化されたコードに依存するのは意味がない」と付け加えることができます。MQLタスクは常に高度に専門化されており、大きなコードの再利用はしばしば効果的ではありません。

HH: MQLコードの主な目標は、テスターで使用したり、1ティック以内にコードを実行したりするために、できるだけ高速であることです。

 
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

この課題は解決され,この例のすべての関数が1つの仮定で一対一に移植されました: 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に関する質問

セルゲイ・デジブリク, 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で 私のバージョンとあなたのバージョンの速度をチェックしてみてください。

レッスン中なので、もう少ししてから速度を確認します