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

 

すべてのボタンが一度に1行しか動作しない場合は、ボタンクラスで行を参照する静的変 数を作成します。しかし、これだけではボタンクラスの可能性を狭めてしまうので、2つの行を並行して操作するために2つのボタンのペアを作ることはできません。

そして、この問題の正しい解決方法は、関数を書いて、その関数に行の参照を渡し、関数がこの参照を目的のボタンオブジェクトに渡すという初歩的なものです。OOPに不思議を求める必要はないのです。

あるいは、2つのボタンを作成するクラスを書くこともできます。

 
Dmitry Fedoseev:

すべてのボタンが一度に1行しか動作しない場合は、ボタンクラスで行を参照する静的変 数を作成します。しかし、それだけではボタンクラスができることが制限されるため、意味がありません。2つの行を並行して操作するために、2つのボタンのペアを作ることはできないのです。

そうですね、ボタンが4組、線が4本あるので、スタティック変数も選択肢から捨てました。

そして、この問題の正しい解決方法は、関数を書き、その関数にラインへのリンクを渡し、このリンクを関数内の目的のボタンオブジェクトに渡すという初歩的なものです。OOPに奇跡を求める必要はないのです。

まあ、あるいは、ボタンを2つ作るクラスを書きます。

そして、私はOOPの奇跡を信じていたのです。)

このような選択肢をありがとうございます。どれが一番自分に合うか考えてみます。

 
Vasiliy Pushkaryov:

問題解決に協力してください。ボタンが2つ、線が1つあります。1つのボタンを押すと編集モードになり、離すとその行が削除されます。 2つ目のボタンは、クリックするとその行を固定し、クリックすると編集モードに戻ります。各ボタンは、ラインオブジェクトの 色と他のいくつかのプロパティを 変更することができます。Line "オブジェクトはグローバルに定義されています。ボタンを作成した直後に、各ボタンに「線」オブジェクトへの参照を渡して、「ボタン」オブジェクトの中で参照変数を操作したときに、すべての変更がグローバルな「線」オブジェクトに記憶されるようにすることは可能でしょうか?

ボタンを押す代わりに、add()関数で "Line "オブジェクトのカウンターをインクリメントする、簡単なスクリプトを以下に示します。関数の引数に「LINE」オブジェクトを参照で渡せるのはわかるのですが、ちょうど作業バージョンで、そういう関数がいくつかあるので、一度、最初に参照を渡したいのです。Btn1.add()やBtn2.add()でgLine.countを増加させることは可能でしょうか。

今はそんな感じでやっています。


もしかして、こんなやり方もあるのかな?

//+------------------------------------------------------------------+
class CLine
  {
public:
   int               count;
                     CLine(void){count=0;};
                    ~CLine(void){};
  };
//+------------------------------------------------------------------+
class CMyButton
  {
private:
public:
   CLine            *m_Line;
                     CMyButton(void):m_Line(NULL){};
                    ~CMyButton(void){};

   void bind(CLine *aLine) {m_Line=aLine;}
   void addition() {if(CheckPointer(m_Line)==POINTER_DYNAMIC){++m_Line.count;}}
  };


CMyButton  Btn1;
CMyButton  Btn2;

CLine *gLine;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   gLine = new CLine;
   Btn1.bind(GetPointer(gLine));
   Btn2.bind(GetPointer(gLine));
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   Print("Line.count=", gLine.count);
   Btn1.addition();
   Print("Line.count=", gLine.count, "  Btn1.m_Line.count=", Btn1.m_Line.count);
   Btn2.addition();
   Print("Line.count=", gLine.count, "  Btn2.m_Line.count=", Btn2.m_Line.count);
   Btn1.addition();
   Print("Line.count=", gLine.count, "  Btn1.m_Line.count=", Btn1.m_Line.count);
   Btn2.addition();
   Print("Line.count=", gLine.count, "  Btn2.m_Line.count=", Btn2.m_Line.count);
  }
//+------------------------------------------------------------------+

2019.07.04 00:44:30.464 1 (EURUSD,H1) Line.count=196

2019.07.04 00:44:30.464 1 (EURUSD,H1) Line.count=197 Btn1.m_Line.count=197

2019.07.04 00:44:30.464 1 (EURUSD,H1) Line.count=198 Btn2.m_Line.count=198

2019.07.04 00:44:30.464 1 (EURUSD,H1) Line.count=199 Btn1.m_Line.count=199

2019.07.04 00:44:30.464 1 (EURUSD,H1) Line.count=200 Btn2.m_Line.count=200

2019.07.04 00:44:31.856 1 (EURUSD,H1) Line.count=200

2019.07.04 00:44:31.856 1 (EURUSD,H1) Line.count=201 Btn1.m_Line.count=201

 
Igor Makanu:

こうあるべきかもしれませんね。

2019.07.04 00:44:30.464 1 (EURUSD,H1) Line.count=196

2019.07.04 00:44:30.464 1 (EURUSD,H1) Line.count=197 Btn1.m_Line.count=197

2019.07.04 00:44:30.464 1 (EURUSD,H1) Line.count=198 Btn2.m_Line.count=198

2019.07.04 00:44:30.464 1 (EURUSD,H1) Line.count=199 Btn1.m_Line.count=199

2019.07.04 00:44:30.464 1 (EURUSD,H1) Line.count=200 Btn2.m_Line.count=200

2019.07.04 00:44:31.856 1 (EURUSD,H1) Line.count=200

2019.07.04 00:44:31.856 1 (EURUSD,H1) Line.count=201 Btn1.m_Line.count=201

はい、イゴールさん、以上です、ありがとうございました。

私はまだポインターについて「あたふた」しているので、あなたの解決策は、私の現在のタスクとポインターの使い 方をさらに理解する上で助けになるでしょう。

ご感想をお寄せいただきありがとうございました。

 
Igor Makanu:

こうあるべきかもしれませんね。

2019.07.04 00:44:30.464 1 (EURUSD,H1) Line.count=196

2019.07.04 00:44:30.464 1 (EURUSD,H1) Line.count=197 Btn1.m_Line.count=197

2019.07.04 00:44:30.464 1 (EURUSD,H1) Line.count=198 Btn2.m_Line.count=198

2019.07.04 00:44:30.464 1 (EURUSD,H1) Line.count=199 Btn1.m_Line.count=199

2019.07.04 00:44:30.464 1 (EURUSD,H1) Line.count=200 Btn2.m_Line.count=200

2019.07.04 00:44:31.856 1 (EURUSD,H1) Line.count=200

2019.07.04 00:44:31.856 1 (EURUSD,H1) Line.count=201 Btn1.m_Line.count=201

また、gLineをポインタとして宣言しているのに、なぜGetPointer(gLine)を使うのですか?)))

また、宣言時にCLineオブジェクトを作成する必要がある。

CLine* gLine=new CLine;

ボタン初期化の段階で、ボタンとラインも初期化する必要があります。

...
                CMyButton(CLine* line):m_Line(!CheckPointer(line)?NULL:line){};
...
CLine* gLine=new CLine;
CMyButton  Btn1(gLine);
 
Vladimir Simakov:

gLineをポインタとして宣言したのに、なぜGetPointer(gLine)を使うのですか?)))

CLineオブジェクトの形成は、宣言する際にも急務となる。

CLine* gLine=new CLine;

ボタン初期化の段階で、ボタンとラインも初期化する必要があります。

夜だったので、なぜそのように書いたのかは不明ですが...。実は寝ていたのですが、携帯のSkypeで目が覚めてしまい、そのまま掲示板をスキップしてしまいました )))

MQLポインタが何であるかを完全に理解しているわけではありませんし、C++のポインタのように動作するわけでは明らかにありません。

私はそれを理解しようとしてきたが、私はポインタが関数https://www.mql5.com/ru/forum/1111/page2470#comment_11796309 のパラメータとしてどのように動作するかを理解していない - 私はそこに関数にポインタを渡すが、実際には私は作成されたポインタの新しいコピーを取得します。

SZY:MQL-pointerのスコープが分からないので、https://www.mql5.com/ru/forum/1111/page2488#comment_12154218 も聞いてみたのですが・・・。どのケースがローカルスコープで、どのケースがグローバルスコープなのか理解できていないようです・・・。というわけで、科学的実験によってMQL-pointerを扱っています(((o(*゚▽゚*)o)))


ワシリー・プシュカリョフ

はい、イゴール、以上です、ありがとうございました。

私はまだポインターを "泳いで "います。ですから、あなたのソリューションは、私の現在の仕事とポインターの使い 方をさらに理解する上で、とても役に立つでしょう。

ご感想をお寄せいただきありがとうございました。

MQL-pointerは独特の挙動をするので、@Vladimir Simakovが書いて いるように、パラメータ付きのコンストラクタを書くと解決する可能性が高いです - 私は通常そうしていますが、抽象的な観点からでしょうか?- この方法は正しいとは言えませんが、便利ですし、常に正しく動作します。また、コンパイラはポインタのバインドを忘れることを許さないでしょう。

if(CheckPointer(m_Line)==POINTER_DYNAMIC)

このチェックは、コンストラクタを呼び出す際にポインタを保存するため、省略することができます。

Ошибки, баги, вопросы
Ошибки, баги, вопросы
  • 2019.05.22
  • www.mql5.com
Общее обсуждение: Ошибки, баги, вопросы
 

なんと、この課題は、2つのオブジェクトが同時に1つの行へのポインタを渡すのを待つことではなかったことがわかった。実はポインターを渡すということだったんです。誰が考えたのでしょう?

newでオブジェクトを作らなくても、どこかにポインタを渡すことができます。ただし、ポインタが渡されるクラスは、ポインタ変数(アスタリスク*付き)を持っている必要があります。

 
Igor Makanu:

夜だから暗いし......なんでそんな書き方したんだろう......。実は寝ていて、携帯のSkypeで目が覚めたので、一応掲示板をざっと見てみました )))

MQLポインタが何であるかを完全に理解しているわけではありませんし、C++のポインタのように動作するわけでは明らかにありません。

私はそれを理解しようとしてきたが、私はポインタが関数https://www.mql5.com/ru/forum/1111/page2470#comment_11796309 のパラメータとしてどのように動作するかを理解していない - 私はそこに関数にポインタを渡すが、実際には私は作成されたポインタの新しいコピーを取得します。

SZY:MQL-pointerのスコープが分からないので、https://www.mql5.com/ru/forum/1111/page2488#comment_12154218 も聞いてみたのですが・・・。ポインタがローカルスコープを持つ場合と、グローバルスコープを持つ場合がまだ理解できていません.全ては、科学実験の手法でMQL-pointerに取り組んでいます((

最初のケースはすべてがシンプルです。実際にスタック上に新しいダイナミック・オブジェクトを作成する、ただそれだけです。に渡す必要があります...(CObj* &jbj,...)

そして、2つ目のケースは、そうしなければならないのです。

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

最初のケースについては、簡単です。実際にスタック上に新しいダイナミック・オブジェクトを作成し、それで終わりです。それを...(CObj* &jbj,...) に渡す必要があります。

そして、2つ目のケースは、そうすべきです。

今夜確認してみます、リファレンスには&の使い方があまり書かれていません。

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

 
また、ポインタは非参照で渡すこともできます(&なし)。