mql5におけるOOP、テンプレート、マクロ、微妙な使い分け - ページ 6

 
Alexey Viktorov:

さあ、どうぞ。

では、すべてのコードは松葉杖で作られているのですか?個人的なことではないんです。
MQLには本格的なOOPがありませんし、バグも多く、定期的に報告しているのですが、なかなかうまくいきません。 バグに対しては松葉杖で自己防衛するしかないのですが、どうしたらいいのでしょう?
 

その方法をご紹介します。

静的変数が定数で初期化されている場合、この初期化は以前と同様にグローバル初期化ステップで行われます。
それ以外の場合(呼び出しや変数の初期化)、最初の呼び出しで静的変数が初期化され(C++のようになる)、この呼び出し自体が暗黙のグローバル変数/フラグで 条件にラップされる、例えば、次のようになります。

MQLコード用

class CFoo { };

void func(bool f)
  {
   if(f)
     {
      static CFoo foo;
      foo.MakeMeHappy();
     }
  }

次のような擬似コードが生成されます。

CFoo static_func_foo={}; // zeromem only
bool static_func_foo_init=false;

void func(bool f)
  {
   if(f)
     {
      if(!static_func_foo_init)
        {
         static_func_foo.CFoo();  // constructor call
         static_func_foo_init=true;
        }

      static_func_foo.MakeMeHappy();
     }
  }
 
Alexey Navoykov:

それでも、関数の中で何らかの方法で分離する必要があります。

必ずしもそうではないし、そうとは限らない。スレッドを散らかさないように、例は挙げません。

 
Ilyas:

その方法はこうだ。

大ニュース! やはり神々は我々の祈りを聞いていたのだ)
 
Alexey Navoykov:
MQLには本格的なOOPが ありませんし、バグも多く、定期的に報告していますが、なかなかうまくいきません。 バグに対しては松葉杖で自己防衛するしかないのですが、どうしたらいいのでしょう?

混乱させられましたね。なら仰せの通りに

トレーディング、自動売買システム、ストラテジーテストに関するフォーラム

mql5の特性、ヒントとコツ

アレクセイ・ナヴォイコフ 2019.01.25 11:44

パラメータが異なる型である場合、対応する型のオーバーロードメソッドを いくつか作るのが合理的です。 いずれにせよ、関数内でそれらを共有しなければならないので、混乱するよりは、別々の関数に分割する方が良いでしょう。さらに、匿名型を取るので、間違って何でも渡してしまい、ライブラリ内でコンパイルエラーになることがありますが、それは良くありません。 あるいは、取得できないかもしれませんが、それも二重に悪いことです)。

つまり、本格的なOOPでは、テンプレート関数は(一部の例外を除いて)松葉づえの ようなものなのです。

それに、MQLには本格的なOOPはないですしね...。松葉杖も行方不明?全く理解できないんです。
 
MQLはOOPで問題ないし、多重継承が追加されれば(今のままでは使い物にならないので、少なくともインターフェースについては)完璧です。
 
Ilya Malev:
MQLはOOPでOK、あとは多重継承(今のままでは使い物にならないので、せめてインターフェースだけでも)を追加すれば完璧です。

つまり、インターフェイスは通常のOOPの基本であり、MQLではすべて問題ないと言うことですね。

 
Alexey Navoykov:

インターフェイスは通常のOOPの基本なのに、MQLではすべてうまくいっていると言うわけですね。

通常のOOPの基本はポリモーフィズムであり、インターフェースではありません。インターフェイスは、ある種のクラス構造の 基礎となるものです。一般的には、このような話題で盛り上がりたいところですが、このスレッドはその場ではありませんね。

 
Ilya Malev:

通常のOOPの基本はポリモーフィズムであり、インターフェースではありません。インターフェイスは、ある種のクラス構造の 基礎となるものです。一般的に、私はこれらのトピックについて喜んで議論したいのですが、このブランチはそれに適していないと思われます。

私たちはMQL言語の特殊性について議論しており、多重継承がないことは非常に特徴的なことです)。

なるほど、確かに基本はポリモーフィズムだが、インターフェースが分離していないと使い勝手が悪い。このため、テンプレートの引数として、インターフェイスではなく、オブジェクトを渡してしまうことがよくあります。

ここでは、複数のインタフェースをシミュレートする私のバリエーションを説明しました。 したがって、クラスは、以下のように宣言することができます。

class A : public Interface1<Interface2<Interface3<CBase>>>
{
 ...
};
 
Alexey Navoykov:

MQL言語の特殊性を議論しているのですが、多重継承がないのはかなりの特殊性です)。

なるほど、確かに基本はポリモーフィズムだが、インターフェースが分離していないと、使っていて不便だ。このため、テンプレートの引数として、インターフェイスではなく、オブジェクトを渡してしまうことがよくあります。

複数のインタフェースを模倣する私のバリエーションはここで 説明したとおりです。 したがって、クラスはこのように宣言することができます。

私見ですが、悪いことばかりではありません。C#の基本的なメインインターフェースは、そのメソッドを1つの基本的なスーパークラスに還元して継承することができないほど多くはない。

追伸:<<<>>>のような構文で複数のものを実装するのは、ちょっと面倒です。例えば、a==b は a.compareto( b ) を、a[comparer]==b は comparer.compare(a,b) を呼び出すなど、演算子を通して機能を実行する方がよいでしょう。