class Base
{
public:
virtualvoid method1(void) { cout << "2\n"; }
};
class Derived: public Base
{
public:
virtualvoid method1(void) override { cout << "3\n"; }
};
template<typename T>
class Wrapper
{
public:
Wrapper(T *ptr)
{
ptr->T::method1();
}
};
int main()
{
Derived d;
d.Base::method1(); // ok
Wrapper<Base> w(&d); // okreturn0;
}
同様のMQLでエラーが発生する。
class Base
{
public:
virtualvoid method1(void) { Print(__FUNCSIG__); }
};
class Derived: public Base
{
public:
virtualvoid method1(void) override { Print(__FUNCSIG__); }
};
template<typename T>
class Wrapper
{
public:
Wrapper(T *ptr)
{
ptr.T::method1(); // <<< 'Base' is not a class, struct or union
}
};
voidOnStart()
{
Derived d;
d.Base::method1(); // ok
Wrapper<Base> w(&d); // causes the error above
それが、クラスツリーには共通のノードCWndがあります(CObjectはさらに遠く、ルート)。
CButton -> CWndObj -> CWnd -> CObject.
メソッドのパラメータをCObjectに変更すると、2倍以上のエラーが発生します。
配列でない場合も、同様のクラス階層が機能します。以下は、コンパイルしたコードです。
問題は、これを配列に対しても機能させる方法です。
テンプレートが役立つのはわかるが、それだけは避けたい。
IMHOは、継承権によってテンプレートなしで動作するはずです。
C++のように確認しました。
効くんです。しかし、MQLはそれを消化しないのです。インデックスがある場合もない場合もです。
C++の場合は、お手本がより明確になります。実行して見てください)))
ああ、悪かったよ。しかし、そこで次のような疑問が湧いてくる。このC++のコードは動作します(すでに正確に動作しています;-))。
同様のMQLでエラーが発生する。
ああ、悪かったよ。しかし、そこで次のような疑問が湧いてくる。このC++のコードは動作します(すでに正確に動作しています;-))。
同様のMQLでは、エラーが発生します。
課題はわからないけど、こういうのを探しているんだろうな。
MQLでは、これはvoid func(void)関数へのポインタです。
は、クラス内で PTR 型のフィールドを宣言し、そこに関数を代入して、「ポインタの参照を解除」して、その関数を呼び出すことができます。
手続き型で書かれた関数をクラスに渡すことは問題なくできますが、クラスメソッドは おそらくそう簡単に渡すことはできません。
タスクはわかりませんが、こんなものを探しているのではないでしょうか?
MQLでは、void func(void)関数へのポインタです。
は、クラス内でPTR型のフィールドを宣言し、そこに関数を代入して、「ポインタの参照を解除」して、その関数を呼び出すことができます。
手続き型で書かれた関数をクラスに渡すことは問題なくできますが、クラスメソッドは おそらくそう簡単に渡すことはできません。
typedef はメソッドでは動作しません。
dynamic_castは継承者(より長い連鎖)に対して働きます。つまり、baseへのポインタがdivedを含んでいる場合、divedにキャストして、それがNULLでなければ(つまり正常にキャストされていれば)、そのメソッドを呼び出すことができるのです。しかし、私の場合のように、逆に、派生するポインタがある場合は、定義上、ベースでもあるのです。そして、その仮想メソッドを呼び出すと、ポインタの中にderivedが「居座って」いることがわかり、オーバーライドされた実装が呼び出されます。ベースとなるものが必要です。
この目的のためにC++では上記のような構文がありますが、MQLはC++ではありません。どうやらまだ方法がないようです。
私は回避策を講じましたが、すべてのタスクでうまく機能するとは限りません。
このタンバリンダンスのポイントは、いつものように、絡まったコードを「ライブラリ」の中に収め、それを使うコードを明確でシンプルなものにすることです。
テスターのrand()を何で初期化するか?
のコードで表示されます。
私はこういう疑似ランダム生成はあまり好きではありません。
テスターのrand()を何で初期化するか?
のコードで表示されます。
私はこういう疑似ランダム生成はあまり好きではありません。
ヘルプ:MathRand
備考
この関数を初めて呼び出す前に、MathSrand を 使って疑似乱数発生器を初期状態に設定する必要があります。
MathSrandで今すぐお試しください。
参考:MathRand
備考
MathSrand 関数は、最初の関数呼び出しの前に使用して、疑似乱数発生器を初期状態に設定する必要があります。
キャップさん、ありがとうございます。
テスターの話です。
このコードはテスターでも動作しません。
テスターであれば、MathSrandを使う必要はないと思うのですが。
しかし、それで解決しない場合は、テスターがある時点でMathSrand(GetTickCount())を強制している可能性が高いです。
次に MathSrand(int(GetMicrosecondCount()%1000000)) を試してみてください。
GetTickCount()は、15.625ミリ秒ごとに値を変更することを忘れないでください。テスターとしては非常に長い時間間隔ですね。
テスターであれば、MathSrandを使う必要はないと思うのですが。
これはドキュメントと矛盾していますhttps://www.mql5.com/ru/docs/math/mathrand
最初の関数呼び出しの前に、MathSrand関数を使って、疑似乱数発生器を初期状態にする必要があります。
ソースコードは見たくないのですが、ニューラルネットワークのパッケージでは、NSの重みのランダムな値による初期化が必須なので、MQLのヘルプ資料に従って行われたのではないかと思います。
つまり、このようなNSパッケージを使ってテスター内でMQLプログラムを使用する場合、おそらく1つのプロセッサコアで行われるでしょう。
srand()がないほうがかっこいい。
これはドキュメントと矛盾しているhttps://www.mql5.com/ru/docs/math/mathrand
ソースコードは見たくないのですが、ニューラルネットワークのパッケージでは、NSの重みのランダムな値による初期化が必須なので、MQLのヘルプ資料に従って行われたのではないかと思います。
つまり、このようなNSパッケージを使ってテスター内でMQLプログラムを使用する場合、おそらく1つのプロセッサコアで行われるでしょう。
srand()抜きでも面白い。
Igor, では MathSrand(int(GetMicrosecondCount()%16384)) を試してみてください。
イメージがどう変わるかですね。