OOP(オブジェクト指向プログラミング)に関する質問 - ページ 11

 

ニュアンスによっては、より経験豊富なプログラマーの意見が欲しいところです。クラス内の変数の宣言を 取る。例えば、あるクラスの異なるメソッド内部で宣言された変数がありますね。各メソッドで最も多く宣言される。これをやる意味があるのか、それともプライベート セクションで一度宣言してから使ったほうがいいのか?

ループで使うのであれば、カウンタ変数を使う方が論理的だと思うのですが、いかがでしょうか?結局、ループを使う場合などは、計算の瞬間にカウンタに明示的に値をセットすることになる。

for (i = OrdersTotal() - 1; i >= 0; i--)
{

}

各メソッドにおいて、変数iを 宣言することは、おそらくメモリセル上のメモリを無駄に消費することになり、合理的ではありません。一般的には、そういうことに興味があるのです。

また、これはループだけでなく、他のオプションにも関係します。複数回宣言しなければならないほど異なる変数があるが、それらは同じ役割を果たす...。ただ、以前の操作で出た「ゴミ」が含まれないように、値をゼロにする必要があるものもあるようです。するのが合理的なのか、それともそのような変数を再宣言するのが簡単なのか...。一般的には、プロの方からお話を伺いたいと思います。

 
hoz:

ニュアンスによっては、より経験豊富なプログラマーの意見が欲しいところです。クラス内の変数の宣言を取る。例えば、あるクラスの異なるメソッド内部で宣言された変数がありますね。各メソッドで最も多く宣言される。これをやる意味があるのか、それともプライベート セクションで一度宣言してから使ったほうがいいのか?

ループで使うのであれば、カウンタ変数を使う方が論理的だと思うのですが、いかがでしょうか?結局、ループを使う場合などは、計算の瞬間にカウンタに明示的に値をセットすることになる。

各メソッドにおいて、変数iを 宣言することは、おそらくメモリセル上のメモリを無駄に消費することになり、合理的ではありません。一般的に、私はそういうことに興味があります。

また、これはループだけでなく、他のオプションにも関係します。複数回宣言しなければならないほど異なる変数があるが、それらは同じ役割を果たす...。ただ、以前の操作で出た「ゴミ」が含まれないように、値をゼロにする必要があるものもあるようです。するのが合理的なのか、それともそのような変数を再宣言するのが簡単なのか...。一般的には、プロの方からお話を伺いたいと思います。

そうすべきかどうかは、その変数を作成する目的によって異なります。注文のようなエンティティがクラスでカプセル化されている場合、そのプロパティ(注文のチケットなど)を表現するために、クラスで定義された変数が必要になります。これらの変数は、そのクラスの同じオブジェクトに対して、そのクラスのすべてのメソッドで共有されます。

メソッド内でループを提供するために変数を作成する場合、その変数はメソッド内で自動的(つまりstaticキーワードを使用せずに)に定義されるべきです。この場合、あるメソッドが自身のループの中で別のメソッドを呼び出し、そのメソッドもループを持ち、同じ名前の変数が使われていたとしても、特に問題はありません。クラスで宣言された変数を使用する場合、2つ目のメソッドのループの中で変数が上書きされます。

自動変数の 場合、関数の入力時に自動的にメモリが確保され、終了時に自動的に削除されるため、オーバーヘッドを最小限に抑えることができます。さらに、関数が単純であれば、コンパイラは自動メモリーの確保と解放を全く行わないコードを生成することも可能である。

この種のメモリーセルを保存することは、少し前までは常識的なことでしたが、20年ほど前についにその意味を失ってしまいました......。

 

クラスがあるんです。これだけシンプルなメソッドを持ちながら、すべてノーブランドで地獄のような、どこにバグがあるのか探していたのですから。

// 1.5 Определяем минимальную разрядность лота. ===========================================================================================
int BaseInfo::LotPrecision()
{
   static int li_LotPrecision = 0;     // устанавливаем минимальную разрядность лота в ноль
   Print ("LotPrecision()_Before: li_LotPrecision = ", li_LotPrecision);
   Print ("LotPrecision()_BeforeCircle: SLots.gd_LotStep = ", SLots.gd_LotStep);
   while (SLots.gd_LotStep < 1)
   {
      Print ("LotPrecision(): SLots.gd_LotStep < 1");
      SLots.gd_LotStep *= 10;
      Print ("SLots.gd_LotStep *= 10");
      Print ("LotPrecision(): SLots.gd_LotStep = ", SLots.gd_LotStep);
      li_LotPrecision++;
      Print ("LotPrecision(): li_LotPrecision = ", li_LotPrecision);
   }
   Print ("LotPrecision(): LOTPRES = ", li_LotPrecision);
   return (li_LotPrecision);
}

変数li_LotPrecisionは、以前は static モディファイアなしでしたが、値を失ってはいけないと思い、変更しました。モディファイアを追加しても、変数li_LotPrecisionの 値が保持されないことに気がつきました

OnInite() にプリントしています。

void OnTick()
{
   int Lot = CBase.LotPrecision();
   Print ("Lot = ", Lot);
}

ログに

17:26:03 2014.07.22 14:10  RSI EURUSD,M5: SLots.gd_LotStep = MarketInfo (_Symbol, MODE_LOTSTEP); = 0.01
17:26:03 2014.07.22 14:10  RSI EURUSD,M5: LotPrecision()_Before: li_LotPrecision = 0
17:26:03 2014.07.22 14:10  RSI EURUSD,M5: LotPrecision()_BeforeCircle: SLots.gd_LotStep = 0.01
17:26:03 2014.07.22 14:10  RSI EURUSD,M5: LotPrecision(): SLots.gd_LotStep < 1
17:26:03 2014.07.22 14:10  RSI EURUSD,M5: SLots.gd_LotStep *= 10
17:26:03 2014.07.22 14:10  RSI EURUSD,M5: LotPrecision(): SLots.gd_LotStep = 0.1
17:26:03 2014.07.22 14:10  RSI EURUSD,M5: LotPrecision(): li_LotPrecision = 1
17:26:03 2014.07.22 14:10  RSI EURUSD,M5: LotPrecision(): SLots.gd_LotStep < 1
17:26:03 2014.07.22 14:10  RSI EURUSD,M5: SLots.gd_LotStep *= 10
17:26:03 2014.07.22 14:10  RSI EURUSD,M5: LotPrecision(): SLots.gd_LotStep = 1.0
17:26:03 2014.07.22 14:10  RSI EURUSD,M5: LotPrecision(): li_LotPrecision = 2
17:26:03 2014.07.22 14:10  RSI EURUSD,M5: LotPrecision(): LOTPRES = 2
17:26:03 2014.07.22 14:10  RSI EURUSD,M5: LotPrecision()_Before: li_LotPrecision = 0
17:26:03 2014.07.22 14:10  RSI EURUSD,M5: LotPrecision()_BeforeCircle: SLots.gd_LotStep = 1.0
17:26:03 2014.07.22 14:10  RSI EURUSD,M5: LotPrecision(): LOTPRES = 0
17:26:03 2014.07.22 14:10  RSI EURUSD,M5: Lot = 0
17:26:03 2014.07.22 14:10  RSI EURUSD,M5: LotPrecision()_Before: li_LotPrecision = 0
17:26:03 2014.07.22 14:10  RSI EURUSD,M5: LotPrecision()_BeforeCircle: SLots.gd_LotStep = 1.0
17:26:03 2014.07.22 14:10  RSI EURUSD,M5: LotPrecision(): LOTPRES = 0
17:26:03 2014.07.22 14:10  RSI EURUSD,M5: Lot = 0
17:26:03 2014.07.22 14:10  RSI EURUSD,M5: LotPrecision()_Before: li_LotPrecision = 0
17:26:03 2014.07.22 14:10  RSI EURUSD,M5: LotPrecision()_BeforeCircle: SLots.gd_LotStep = 1.0

これは、LotPrecision() 関数を終了した後、変数li_LotPrecisionの 値が失われて いることを明確に示しています。どうすれば一定に保てるか?

このli_LotPrecision 変数をprivate class セクションに追加して、後でstatic modifier に代入しようとしましたが、コンパイラは不可能だと言い張ります。

unresolved static variable 'BaseInfo::li_LotPrecision'  BaseInfo.mqh    60      10

この変数は他のどこにも必要とされないので、クラスから放り出すのは意味が ありません。

どうすればいいのか?