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

 
Dmitry Fedoseev:

標準ライブラリは、コントロールがフォーム上に作成されることを前提にしています。そのままでは全く機能しないことになっているのです。少なくとも、昔はそうだった。

KajarskiのGUIシリーズの最新版を試してみないと。どれだけ早く効果が出るかそして、開発者の発案に手を加えるために、再び手紙を書く。
 
Vasiliy Pushkaryov:
KajarskyのGUIに関する記事シリーズの最新版を試してみる必要がありそうです。どれだけ早く効果が出るかそして、もう一度、開発者に書き込んで、その発想を微調整してもらう。

皆同じ輪の中にいる)))- 私がMQLの機能を勉強し始めたのは、このグラフィカル・インターフェースに関する 連載がきっかけでした.- 体験談はイマイチ、記事中の例のいくつかはコンパイルできなくなった、作者は連絡を取り合っているが、ライブラリのサイズが非常に大きい、成功するかもしれないが、私はこのライブラリを使い始めていない。

C#を1週間勉強するか、VSのフォームデザイナーはDelphiと同じだし(さっきはDelphiで書いた)、とにかくSBを使うか。

 
Igor Makanu:

皆同じ輪の中にいる)))- 私がMQLの機能を勉強し始めたのは、このグラフィカル・インターフェースに関する連載がきっかけでした.- 体験談は、記事にある例の一部がコンパイルできなくなった、著者は連絡を取り合っているが、ライブラリのサイズが非常に大きい、成功するかもしれないが、私は使い始めていない。

C#を1週間学ぶか、VSのフォームデザイナーはDelphiと同じだし(Delphiでは先に書いた)、とにかくSBを使うか、少なくとも開発者のサポートがある。

図書館がすでにラッピングされているとのことで、残念です。1年ほど前に試したのですが、パネルの見た目が良かったんです。MT4用に手を加えて試したりもしましたが(Canvasの違いもあり、すぐにはコンパイルできませんでした)、その後、私のタスク用に移植することが困難なため、SBをとりました。GUIは また後日と思った。

C#を1週間でマスターできるとは思えません。しかし、目標を設定しなければなりません。しかも、すでに.NETライブラリのネイティブサポートがあります。ここでは、あなたの特定のタスクにどのように使用できるかを提案しました。

 
Vladimir Simakov:

そして、2つ目のケースでは、次のことが必要です。

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

これは私のアイデアの始まりに過ぎない

テンプレートにバイナリファイルへの書き込みと読み込みを実装したいのですが(テキストファイルでも可能ですが、それは重要ではありません)、クラスフィールドのテンプレートを使用してCDataをファイルに書き込む方法がわかりません - しかし、私は本当にそれをしたいです

 
Igor Makanu:

私はテンプレートでバイナリファイルへの書き込みと読み込みを実装したいのですが(テキストファイルへの書き込みも可能ですが、それは重要ではありません)、テンプレートを使って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は 扱ったことがないのですが、ソースが単純なので(ちなみに、なぜかモディファイアconstなしの仮想メソッドSaveがあります)、一気に解決しました。


SZY そう書いたほうがわかりやすいですね。

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

そうすれば、コンストラクタ/デストラクタは不要になります。new/deleteは本当に便利なところで使うのが理にかなっています。それ以外の場合は、上記のFILEと同じようにすればよい。

 
fxsaber:

CListとCObjectを扱ったことはありませんが、ソースコードがシンプルなので、すぐに動きました。

おお!こんなに早く答えが出たんですね。- ありがとうございました。- 夜、やることがある。

私もCListとCObjectのソースは、読んで、問題が表示されませんが、テストは、実施する必要があります。

ZS: ここで、私が手に入れたいものは...。のような、普遍的なリストです。

1. クラス構造を 生成時に即座に追加できるようにしたもの(実装済み - サンプルで確認 data.AddValue(new CData(i,i*2.0))- OK)

2. 「DB」ファイルへの書き込み、読み込みが可能なもの(書き込み開始、今のところテンプレートコンストラクタは

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 がディスクから作成されるときにデータベースを読み込み、デストラクタが呼ばれるときにディスクに書き込む。

....

ZSです。

なにがいいたいの?-私はちょうど標準的なスキームに従ってEAを書く - マジシャンと注文を検索することにより、注文とすべての操作は、TSが "101指標 "が、より複雑ではない場合、通常2マジシャンは十分ですが、TSは80保留中の注文を監視している場合(注文の10グリッド、グリッドが再オープンしていますと...)。正直言ってバカバカしいのですが、2回目に遭遇しました)、それからいろいろなトリックを使い始め、80の生成されたマジシャンに80のオーダーを導くのです ))) 。- 私はそれを抜け出したが、私はそれをすべて好きではない

私は最終的に私が注文(他のすべて)のデータを書き込むことができるだろうし、最も重要なのは、データベース自体に注意を払わない小さなデータベースを作成したい -配列要素への アクセス、EAが起動またはオフになったときにファイルへの読み取りおよび書き込み

などなど ))))


fxsaber

SZZ 書きやすくなった

それなら、コンストラクタ/デストラクタは必要ない。new/deleteは本当に便利なところで使うべきものです。それ以外については、上記のFILEと同じようにすればよい。

ありがとうございます、でもまだ考えないと・・・というか、後で考えなくて済むような形にしたいです)))- OnInit()でデータベースを作成するときにファイルを読み、DeInit()でデータベースを終了させるときにファイルを保存し、DeInit()で削除し損ねると、ターミナルがそのことをジャーナルに書き込む...というものです。私見では、データベースを操作する際のエラーは除外しています...。一般に、やればわかる、便利さ

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

もしよろしければ、なぜ " :: " を使うのでしょうかhttps://www.mql5.com/ru/docs/basis/operations/other

 
Igor Makanu:

もしよろしければ、なぜここで" :: "を使うのでしょうか?

そうでなければ、親クラスに同じ名前のメソッドがないことを確認する必要があります。また、仮になかったとしても、誰かが追加すれば、そのコードは動作します。

同じ理由で、私は曖昧さをなくし、読みやすくするために、いつもこれを使います。


ZZY でも、まれにしかない状況 :: で、これが柔軟性を奪ってしまうんです。メソッド本体をクラスの中に書いた方がいい場合と、外に書いた方がいい場合についても、同様の微妙な違いがある。私はこのようなことに遭遇した記憶があるが、例は挙げないことにする。

 
fxsaber:

そうでなければ、親クラスに同じ名前のメソッドがないことを確認する必要があります。また、仮になかったとしても、誰かが追加すれば、そのコードは動作します。

同じ理由で、私は曖昧さをなくし、読みやすくするために、いつもこれを使います。

そうですね、本当に実用的でバグも防げますし、考慮に入れておきます

ありがとうございました。

 
Igor Makanu:

4. ファイル書き込みフラグ m_fsaveが有効な場合、AddValue()メソッドを呼び 出すたびに、ファイルにデータが追加されます。

CListのレコード形式を見る。無視してるんですね。