エラー、バグ、質問 - ページ 1891

 
Renat Fatkhullin:

もちろんです。

本当ですか?なぜなら、dynamic_castは親から子へのボトムアップの変換に最もよく使われるからです。

しかも、MQLでは、本来なら鋳造できないはずの下から上へも完璧に鋳造できるのです。

class A
{
public:
   virtual void f()
   {
      Print("1");
   }
};

class B: public A
{
public:
   virtual void f()
   {
      Print("2");
   }
};

void OnStart()
{
   A* ptr1 = new B();
   ptr1.f();
   A* ptr2 = new A();
   ptr2.f();
   
   B* casted = dynamic_cast<B*>(ptr1);
   casted.f();
   
   B* casted1 = dynamic_cast<B*>(ptr2);
   casted1.f(); // здесь должна быть ошибка потому что casted1 должен быть null
   delete ptr1;
   delete ptr2;
}

вывод:
2017.05.13 18:30:14.864    t ETHUSD,M5: 2
2017.05.13 18:30:14.865    t ETHUSD,M5: 1
2017.05.13 18:30:14.866    t ETHUSD,M5: 2
2017.05.13 18:30:14.867    t ETHUSD,M5: 2


レナト・ファットフーリン

ここで、MQL5のコードフラグメントをご覧ください。

そう、うまくいかないはずで、それはすでに上で説明されていることですが、ボトムアップキャストが不可能だからではありません。

 
Konstantin:
ポインタを上から下へ、つまり親へキャストした後、そのポインタをスコープ内のどこかへ渡すと、子孫のフィールドはそこで利用可能になるのでしょうか?

はい、ご質問の例を挙げます。

class CLASS1
  {
public:
   int               i;
  };
class CLASS2 : public CLASS1
  {
  };
void OnStart()
  {
   CLASS1 _object;
   CLASS2 *_ptr=dynamic_cast<CLASS2 *>(&_object);

   if(!_ptr)
      Print("CLASS1 -> CLASS2 failed, null");

   CLASS2 *my=new CLASS2;
   CLASS1 *my_ptr=my;
   CLASS2 *my_ptr2=dynamic_cast<CLASS2 *>(my_ptr);

   if(my_ptr2)
     {
      Print("CLASS2 -> CLASS1 -> CLASS2 ok");
      my_ptr2.i=1;
     }
   Print("Value: ",my.i);
  }
と出力します。
2017.05.13 18:34:50.341 cast (EURUSD,H1)        CLASS1 -> CLASS2 failed, null
2017.05.13 18:35:18.933 cast (EURUSD,H1)        CLASS2 -> CLASS1 -> CLASS2 ok
2017.05.13 18:35:20.110 cast (EURUSD,H1)        Value: 1

まず、未解決のキャストを下から順にチェックし、NULLを取得します。これは正しい。

次に、CLASS2オブジェクトを作成し、その親クラスへの参照を割り当てます(ここで重要なのは、CLASS2オブジェクトの元の型がそのメタ情報に格納されていることを、環境が動的に知っていることです)。次に、(ご質問のように)参照 CLASS1 から CLASS2 に動的にキャストします(ソースオブジェクトのメタ情報に基づく変換権チェック付き)。

キャストの結果を確認し、変数i = 1に書き込む。最後に、最初に作成したオブジェクトを 参照しながら、iの値を出力します。

すべてが正しく、仕様通りに動作します(C++自体のdynamic_cast仕様も含む)。

 
Комбинатор:

本当ですか?なぜなら、dynamic_castは親から子へのボトムアップの変換に最もよく使われるからです。

しかも、MQLでは、本来なら鋳造してはいけないところでも、下から上へ完璧に鋳造してしまうのです。

その通りです。

最新のビルドにアップデートすることをお忘れなく。現在、1598でテストしていますが、このスレッドに最近zip形式で投稿されたものだと思います。

 
Renat Fatkhullin:

最新のビルドにアップデートすることをお忘れなく。

そう、旧ビルドです。

レナト・ファットフーリン

そうなんです、下から上への運転はできず、上から下への運転しかできないんです。これは安全のためです。

これは誤解を招くし、dynamic_castの機能と直接矛盾しているので、消去した方がいい。
 
Комбинатор:

そう、旧ビルドです。

これは誤解を招きやすいし、dynamic_castの機能とも直接矛盾している。

CLASS1→CLASS2の頭文字をとったキャスティングの例として上げられた通り、正しく理解されましたね。そういうキャスティングが、ほとんどの人の頭の中にあるんです。

また、dynamic_castの安全性チェックの核となるのは、「下から上にはキャストできず、上から下へしかキャストできない」という点です。

分かる人には分かる、dynamic_castの真髄。

 
Renat Fatkhullin:

最新のビルドにアップデートすることをお忘れなく。現在、1598でテストしていますが、これは最近このスレッドにzipとして投稿されたものだと思います。

コンパイラとエグゼキュータはどのようなexeファイルに収まっているのですか?

今、MT4b1080はMEb1599を動かしています。metaeditor.exeとterminal.exeが何をするものなのか説明してください。

 
fxsaber:

コンパイラとエグゼキュータはどのようなexeファイルに収まっているのですか?

MT4b1080は、現在MEb1599が動作しています。metaeditor.exeとterminal.exeが何をするものなのか説明してください。

コンパイラは両プラットフォームで共通です。metaeditor.exeの中にあります。
 
Renat Fatkhullin:
両プラットフォームのコンパイラは同じものです。metaeditor.exeの中にあります。
また、同じdynamic_castをチェックするexecutorは、terminal.exeにあるのでしょうか?
 
fxsaber:
また、同じdynamic_castをチェックするexecutorは、terminal.exeにあるのでしょうか?
もちろん
 
Renat Fatkhullin:
また、こんな質問も。