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

 
Dmitry Fedoseev:
また、ポインタは非参照で渡すこともできます(&なし)。
はい、できます。しかし、&なしでポインタを渡すと、スタック上に新しいポインタが生成され、そこに渡された値が代入される。また、関数内でこのポインタでメモリを確保すると、スタック上に生成されるポインタが変化するため、スタックを展開する際にメモリリークが発生する。もちろん、それはよくないことなのですが、もし、そうしたいと思ったら......。
 
Vladimir Simakov:
このようにデストラクタが呼ばれると、スタック上に作られたポインタが変更され、その結果、スタックを「巻き戻す」ときにメモリリークが発生します。もちろん、そんなことをするのはよくないのですが、もし、そうしたいと思ったら......。

MQLのクラスへのポインタの挙動は予測できません。ある管理者は、すべてのクラスはグローバルメモリに作成される(メモリ割り当て)と書いていましたが、あなたはローカルスコープのクラスへのポインタはスタックに作成されると書いています(イミフ、そうあるべきです!)。

テストクラスのデストラクタにPrint() を登録しておけば、ローカルスコープを出るときに自動的にデストラクタが呼ばれるはずなので、理論的には難しいことではないのですが...。

 
Vladimir Simakov:
はい、できます。ポインタを&なしで渡した場合のみ、スタック上に新しいポインタが生成され、そこに渡された値が代入されます。そして、関数内でこのポインタでメモリを確保すると、スタック上に生成されたポインタが変化するため、スタックを展開する際にメモリリークが発生する。もちろん、それはよくないことなのですが、もし、そうしたいと思ったら......。

漏れることはないでしょう。なぜなら、誰もこのポインタに関数の中で何かを割り当てていないからです。

 
Igor Makanu:

MQLのクラスへのポインタの挙動は予測できません。ある管理者は、すべてのクラスはグローバルメモリに作成される(メモリ割り当て)と書いていましたが、あなたはローカルスコープのクラスへのポインタはスタックに作成されると書いています(イミフ、そうあるべきです!)。

テストクラスのデストラクタにPrint()を登録し、ローカルスコープを出るときにデストラクタが自動的に呼ばれるようにすればいいだけなので、理論的には難しくないのですが...。

メモリを動的に確保(new)した場合はヒープに、スタック上にオブジェクトを作成(CObj obj;)した場合はスタック上にもメモリが確保されます。

 
Dmitry Fedoseev:

漏れることはないでしょう。なぜなら、誰もこのポインタに関数の中で何も割り当てていないからです。

void CreateLabel(CChartObjectLabel *l,string name,int y)
  {
   l=new CChartObjectLabel;
   l.Create(0,name,ChartWindowFind(),0,y);
   l.Color(clrYellow);
   l.FontSize(14);
   l.Description(name);
  }

これは典型的なリークです。スタック上に作成され、関数に渡された値で作成時に初期化されたポインタは、新しい値が割り当てられ、新しいオブジェクトへのポインタとなりました。その後、スタックを展開する際にポインタを安全に殺すことができました。それこそが、私たちが証明しなければならないことなのです。これはまさに、あるべき姿です。

void CreateLabel(CChartObjectLabel* &l,string name,int y)
 
Vladimir Simakov:

メモリを動的に確保(new)した場合はヒープに、スタック上にオブジェクトを作成(CObj obj;)した場合はスタック上のそのオブジェクトにもメモリを確保する。

mqlには、そのようなものはありません - (CObj obj;).

 
Vladimir Simakov:

定番のリーク。スタック上に作成され、作成時に関数に渡された値で初期化されたポインタに、新しい値が割り当てられ、新しいオブジェクトへのポインタとなりました。その後、スタックを展開する際にポインタを安全に殺すことができました。それこそが、私たちが証明しなければならないことなのです。これはまさに、あるべき姿です。

神の贈り物と卵を混同しないでください。誤っていることを証明するために、バカなコードを書くのはもっといいことだ......。

 
Dmitry Fedoseev:

mqlにそのようなものはない - (CObj obj;)

いつも使っているんだ。
 
Vladimir Simakov:
void CreateLabel(CChartObjectLabel *l,string name,int y)
  {
   l=new CChartObjectLabel;
   l.Create(0,name,ChartWindowFind(),0,y);
   l.Color(clrYellow);
   l.FontSize(14);
   l.Description(name);
  }

定番のリーク。スタック上に作成され、作成時に関数に渡された値で初期化されたポインタに、新しい値が割り当てられ、新しいオブジェクトへのポインタとなりました。その後、スタックを展開する際にポインタを安全に殺すことができました。それこそが、私たちが証明しなければならないことなのです。これはまさに、あるべき姿です。

なぜ、関数に渡された ポインタを 意図的に再代入 するのですか?もちろん、リークもあるでしょう。しかし、これは「古典的なリーク」ではなく、オブジェクトへのポインタを扱う際の古典的なエラーである。

ここでは新しいオブジェクトを作成する必要はなく、関数に渡されたポインタの外部オブジェクトを処理します。

 
Vladimir Simakov:
いつも使っているんだ。

どこで、どのように?