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

 
Dmitry Fedoseev:

また、鳥といえば、ディスクリプタはポインタでもある。そして、ディスクリプター、ポインター、識別子など、言葉そのものからは何も変わりませんよね。

この言葉の物理的な実装は、長い間、ユーザーから隠されてきました。

斯く斯く然り

- 記述子 - は、システムでこの機能を実装するメソッドに結びつけられます。

- ハンドル - 全てがディスクリプタと同じだが、OSが実装している

- ポインタと識別子は、物理メモリを扱うためのものです。

 
Dmitry Fedoseev:

また、関数にポインタを渡して関数内にオブジェクトを作成する必要がある場合、そのような仕組みになっています。

class CObj{
   public:
   int f(){
      return(33);
   }
};

CObj * obj;

void OnStart(){
  z(obj);
  delete(obj);
}

void z(CObj & o){
   o = new CObj();
}
実はこれが、あなたがOOPについて知りたかったけど、聞くのが怖かったことのすべてです)))

うんうん、天才だね。

この17行が、実はフェドセーエフのプログラマーとしての資質を知るためのすべてなのだ。

2019.07.05 15:19:56.309 'test13.mq5' (11,5)の無効なポインタ・ アクセス

 
Vasiliy Sokolov:

こんにちは。コンピュータのメモリは、スタックとヒープのどちらのコンテキストで使われても同じ性能になります。 動的メモリ管理自体はゴミ収集器の実装に依存します。例えば、Pythonのような参照カウント(より遅いバージョン)や、バックグラウンドプロセスで実行グラフのトラバースを行うオブジェクト生成エポックの分析(Net CLR)などがあります。MQLでどのようなバリエーションが使われているかは不明ですが、MQL5のユーザーは直接delete演算子にアクセスできるため、GCの作業自体が大幅に簡略化され、非常に効率的であると推測されます。したがって、newを使用する際のオーバーヘッドに関する懸念は杞憂に過ぎず、自由にダイナミックメモリを使用することができます。

スタックオーバーフロー」については、現代のシステムでこのケースに遭遇するのは、複雑な再帰を使用する場合や再帰アルゴリズムにミスがある場合のみです。最近のプログラムは、常に仮想アドレス空間のOC protected modeで動作し、メモリページをダイナミックにロードするので、スタックがオーバーフローすることはありません:)。

巧みな解説をありがとうございました。
なぜか、mqlではヒープで呼び出すよりスタックで呼び出す方が速いと思っていました。特に、ゴミ収集器の実装がわからないので。
だから、オブジェクトの生成を 高速化するには、オートとダイナミックのどちらを使うのがいいのか、そんな疑問があるんです。
しかし、例えば、取引依頼の送信を考えてみましょう。
そして、私たちの課題は、迅速な処理性能を実現するために最も正しいオブジェクトを作成することです。
取引要求のメソッドを記述したユーザークラスがあります。
クラスのインスタンスとメソッドの数がわかる。
そして、ご指摘の通り「積み重ねは終わらない」のです。

そこで質問ですが、オブジェクトの作成と削除はどの方法が良いのでしょうか?自動的か動的か?
自動運転オブジェクトの合成管理全般を行うというアイデアがありました。
つまり、ユーザー関数の本体で自動オブジェクトを宣言する。
この方法では、オブジェクトはスタック上に生成されます(理論的には、ヒープよりも高速です)。 オブジェクト変数は、ユーザー定義関数
で、自動オブジェクトは、関数内の動的変数のルールに従って、ユーザー関数自身によって破壊されていないか追加でチェックされます。
そこで、この支部の参加者で、この点について考えている人の意見を十分に聞きたいと思います。

 
TheXpert:

うんうん、天才だね。

この17行が、実はフェドセーエフのプログラマーとしての資質を知るためのすべてなのだ。

2019.07.05 15:19:56.309 'test13.mq5' (11,5)の無効なポインタ・アクセス

驚きです。そして、どちらもエラーなくコンパイルして(今現在)、正常に動作しています。

次回はフォトショップで描いてください。

 
Roman:

巧みな解説をありがとうございました。
なぜか、ヒープ上よりもmqlのスタック上で呼び出す方が、特に屑コレクタがどのように実装されているのか分からないので、高速だと思ったのです。
だから、オブジェクトの生成を 高速化するには、オートとダイナミックのどちらを使うのがいいのか、そんな疑問があるんです。
しかし、例えば、取引要求の送信を考えてみましょう。
そして、私たちの課題は、迅速な処理性能を実現するために最も正しいオブジェクトを作成することです。
取引要求のメソッドを記述したユーザー定義クラスがあります。
クラスのインスタンスとメソッドの数がわかる。
そして、ご指摘の通り「積み重ねは終わらない」のです。

そこで質問ですが、オブジェクトの作成と削除はどの方法が良いのでしょうか?自動的か動的か?
自動運転オブジェクトの合成管理を全般的に行えるようにするアイデアがありました。
つまり、ユーザー関数の本体で自動オブジェクトを宣言する。
この方法では、オブジェクトはスタック上に生成されます(理論的には、ヒープよりも高速です)。 オブジェクト変数は、ユーザー定義関数
で、自動オブジェクトは、関数内の動的変数のルールに従って、ユーザー関数自身によって破壊されていないか追加でチェックされます。
そこで、この支部の参加者で、この点について考えている人の意見を十分に聞きたいと思います。

あなたの考えは正しい。newで作成したオブジェクトへのアクセスは、かなり遅くなります。そして、ここにはゴミ収集人がいません。

 
Igor Makanu:

この言葉の物理的な実装は、長い間、ユーザーから隠されてきました。

imho こんな感じ。

- 記述子 - この機能をシステムで実装するメソッドに結びつけます。

- ハンドル - 全てがディスクリプタと同じだが、OSが実装している

- ポインタと識別子は、物理メモリに対する操作であることを意味する。

そして、その仕組みは、私たちにとって何の違いもないのです。

 

別件で一言。CButtonから子クラスCMyButtonを作成すると、ボタンを作成した後、クラスの外でそのプロパティを変更することができます。 以下はOnInit()で行われます。

しかし、子クラスの内部に追加のフィールドを作り、CButtonクラスの組み込みプロパティを新しい関数で使用したい場合、どのようにすれば正しく実装できるでしょうか?

CButtonクラスでは、クラスメンバm_buttonがprivateセクションで宣言されています。

#include <Controls\Button.mqh>

class CMyButton : public CButton
{ 
  private: 

  public: 
              CMyButton(void){}; 
             ~CMyButton(void){}; 
             
        bool    isPrevState;        // состояние кнопки на предыд.тике, true - была нажата     
        void    setButton();        // создаем кнопку
        void    setProp();          // задаем в ходе программы свойства
}; 

void CMyButton::setButton(void)
{
  // как в этой функции создать кнопку? Я не могу вызвать метод Create()
}

//+------------------------------------------------------------------------------------------------------------------+
//| 
//+------------------------------------------------------------------------------------------------------------------+

CButton Btn;
CMyButton MyBtn;

int OnInit()
  {
  
   Btn.Create(0, "Btn", 0, 50, 50, 120, 75);
   Btn.Text("Standart");
   MyBtn.Create(0, "MyBtn", 0, 50, 200, 150, 225);
   MyBtn.Text("MyBtn");
   
   return(INIT_SUCCEEDED);
  }
 
Dmitry Fedoseev:

そう、EAを書くプログラマーが退屈しないように、メモリリークに関するメッセージを削除して書いてくれるんだ。

昨日はメモリリークがあったのに、今日はそれすらあり得ないというのは面白いですね。

そして、鳥といえば...ディスクリプタはポインタでもある。それに、ディスクリプタでもポインタでも識別子でも、その言葉自体は何も変わらないでしょ。

プロセスのアドレス空間から漏れる。while(true)ループでリークすると、結局、ヒープからの次のメモリ割り当てで、プログラムがクラッシュしてしまいます。
 
Dmitry Fedoseev:

そして、どちらもエラーなくコンパイルして(今現在)、正常に動作しています。

そう、すでに2人の無関係な人があなたのコードのクラッシュをフォトショップで加工しているのです )

あなたのコードは正しく動作しません、それはコード自体を見れば明らかです ))

 
TheXpert:

そう、無関係の二人がすでにあなたのコードをフォトショップで加工しているのです )

あなたのコードは正しく動作しません、それはコード自体を見れば明らかです ))

ちょうど今、同じことを書きたかったのですが))))