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

 
Igor Makanu:

typedefはトピックです、私はそれを試してみましたが、うまくいきませんでした、私はまだ私が台無しにした場所を理解する必要があります、私の例はtypedefでも動作するはずです!。

上に書いたようなコードで動くはずです。自分で確認したかったのですが、ダメでした:=))))))))))))))))))))))))))))))))))))))))))))))


(1961年製)

 
Igor Makanu:

typedefはトピックです、私はそれを試してみましたが、うまくいきませんでした、私はまだ私が台無しにした場所を理解する必要があります、私の例はtypedefでも動作するはずです!。

しかし、不必要なブラケットやポインタを使わず、よりシンプルでエレガントなものにすることができます。

#property strict

class CObject{ };
class CMyclass: public CObject {
  public: CMyclass *operator[] (CObject*p){ CMyclass*r = dynamic_cast<CMyclass*>(p); 
                                return CheckPointer(r)!=POINTER_INVALID?r:NULL; }
          int f(){ return 1; } 
} my ;

void OnStart()
{
  CObject*co=new CMyclass;
  
  my[co].f();
}
 
Ilya Malev:

不必要なブラケットやポインタを排除して、もっとシンプルでエレガントなものにできないでしょうか。

私のオブジェクトは動的に生成され、名前さえも割り当てられませんが、あなたの例ではポインタ名を使用しています。


#property strict
#include <Object.mqh>
#include <Arrays\List.mqh>
//+------------------------------------------------------------------+
class CMyclass:public CObject
  {
public:
   int               x;
   double            y;
   CObject           *obj;
   void              CMyclass(void):x(-1),y(-2.2)  {                       }
   public: CMyclass *operator[] (CObject*p){ CMyclass*r = dynamic_cast<CMyclass*>(p); 
                                             return CheckPointer(r)!=POINTER_INVALID?r:NULL; }         
  };
//+------------------------------------------------------------------+
void OnStart()
  {
   CList *base=new CList;
   for(int i=0;i<3;i++)
     {
      base.Add(new CMyclass);
      ((CMyclass*)base.GetCurrentNode()).x = 99;
      ((CMyclass*)base.GetCurrentNode()).y = 555;
      CMyclass[base.GetCurrentNode()].x = 111;
     }

   for(int i=0;i<3;i++)
     {
      Print(((CMyclass*)base.GetNodeAtIndex(i)).x," : ",((CMyclass*)base.GetNodeAtIndex(i)).y);
     }
   delete base;
  }
//+------------------------------------------------------------------+

SZZ: おっしゃることを少し理解し始めたのですが、まだ結果が出ません。dynamic_cast <>を使わずに、*CObject フィールドを追加して、理論上はこのようになるはずです。

...
 CObject           *obj;
 CMyclass          *operator[](CObject*p)        { obj = p; return(obj); }          
  };

dynamic_cast <> を使った例より少し速く動くと思います。

 
Igor Makanu:

MQLで*CObjectポインターを参照解除することは可能ですか?

このスクリプトは、リンクリストに3つのMyclass要素を追加し、CMyclassフィールドの値を変更するもので、動作します。

中間ポインターのCMyclass *result なしで、動的に作成されたCMyclass要素のフィールドを修正することは可能ですか?

このように、(CMyclass *)(base.GetCurrentNode()).x = 99;

追記:typedefを使う必要があると思われますが、今のところ失敗しています。

あなたが書いたことは、暗黙の了解で使っているに過ぎません。

result=base.GetCurrentNode();

つまり、このような匿名ポインタは、本質的には単なる構文上の糖分である。MQLにはほとんど砂糖がないので、そういうわけにもいきません。しかし、子孫へのキャストは チェックや変換なしに行われるので、明示的なポインタを扱うのが嫌な理由がよくわからないことに注意しなければなりません。

 
Igor Makanu:

ZS:あなたが提案するものを理解するために少し始めたが、まだ結果はありません、あなたはdynamic_cast <>せずに行うことができ、フィールドを追加* CObject 、理論的には、それは次のようになるはずです。

dynamic_cast <> を使った例より少し速く動くと思います。

上記の提案のように、別のフィールドを用意しなくても、演算子でラップすることで可能です。

ちょっとした違いがあるんです。もし突然 myclass に変換されていないオブジェクトが現れたら、 dynamic_cast がなければ実行エラーに なり、その結果 NULL が返されます。すぐに.xでアドレス指定しても、どうせ実行エラーになるので、気にする必要はありません =)))

もし、ドクターの指示通りにすれば、エラー処理のために作られた特別なクラスのインスタンスのようなものが返ってくるはずです ))))

追伸:最近、dynamic_castaの速度を通常のキャストと比較してみたところ、期待するクラスと等しい場合には、ほぼ同じ速度でした。

P.S.S. いずれにせよ、forはかなり寂しい感じです。リストを扱うときは、for eachのようなループを使うべきでしょう(私のループのように)。
 
Igor Makanu:

does not pass compiler: '[' - name expected tst_cast.mq4 32 15

#property strict
#include <Object.mqh>
#include <Arrays\List.mqh>
//+------------------------------------------------------------------+
class CMyclass:public CObject
  {
public:
   int               x;
   double            y;
   CObject           *obj;
   void              CMyclass(void):x(-1),y(-2.2)  {                       }
   public: CMyclass *operator[] (CObject*p){ CMyclass*r = dynamic_cast<CMyclass*>(p); 
                                             return CheckPointer(r)!=POINTER_INVALID?r:NULL; }         
  };
//+------------------------------------------------------------------+
void OnStart()
  {
   CList *base=new CList;
   for(int i=0;i<3;i++)
     {
      base.Add(new CMyclass);
      ((CMyclass*)base.GetCurrentNode()).x = 99;
      ((CMyclass*)base.GetCurrentNode()).y = 555;
      CMyclass[base.GetCurrentNode()].x = 111;
     }

   for(int i=0;i<3;i++)
     {
      Print(((CMyclass*)base.GetNodeAtIndex(i)).x," : ",((CMyclass*)base.GetNodeAtIndex(i)).y);
     }
   delete base;
  }
//+------------------------------------------------------------------+

...

実際にこのラッパーで何ができたのでしょうか?絶対に不要なのに不要なdynamic_cast?ラッパー自身は、CMyClassへの変換を明示的に行っています。つまり、コードが複雑になる一方で作業量は0%です(インデックス参照演算子が、渡されるクラスの明示的な変換演算子として使われています-まあ、まったくもって明らかではありませんが)。

 
Ilya Malev:
リストを扱うときは、for eachのようなループを使うべきでしょう(私のループのように)。

申し訳ありませんが、それは愚かなことです。

 
Vasiliy Sokolov:

あなたが書いたことは、暗黙の了解で使っているに過ぎません。

つまり、このような匿名ポインタは、基本的には単なる構文上の糖分です。MQLにはほとんど砂糖がないので、そういうやり方はできません。しかし、子孫へのキャストは 何のチェックも変換もなく行われるので、ポインタを明示的に操作することがなぜそんなに面倒なのか、はっきりしないことを指摘しておきます。

はい、理解しました。MQLでポインタを扱うときの構文にまだ戸惑っています。標準のC++と同じようですが、常に混乱していて、すぐに何かを書くことも、標準のMTからライブラリのコードを正しく読むこともできません...package髪を全部抜いたよ!... でも、まだ.operaのままです!))))- とにかく何とかしてみます ;)


イリヤ・マレフ

小さな違いがあります。もし myclass に変換されていないオブジェクトがあった場合、 dynamic_cast なしでは実行エラー になり、 dynamic_cast を使うと NULL が返されるだけです。これは、すぐに.xでアドレス指定すると、いずれにせよエラーになります。

私はこのすべてを理解し、それは小さな違いではない、私は心からプロのプログラマのコードは、まさにこの違いでアマチュアのものと異なっていることを言うだろう - 重要なエラーをチェックする際に......。ただし、最近のプログラミング言語の傾向として、無精なプログラマのために try except finally などで簡略化されています;)。

 
Vasiliy Sokolov:

申し訳ないが、これは愚かなことだ。

あ、お願いします。

 
Igor Makanu:

はい、すべて理解しました。MQLでポインタを扱うときの構文がわからないのです。標準のC++と同じようですが、常に混乱していて、すぐに何かを書くことも、標準のMTから同じライブラリのコードを正しく読むこともできません...納品です。髪を全部抜いたよ!... でも、まだ.operaのままです!))))- 答えを出す)

MQLの場合、C++を基準にするとうまくいきません :)MQLで不可能なことのボリュームは、「互換性のある」構成のボリュームよりもはるかに大きいのです。MQLは、構文解析がまったくできないC#を切り詰めたようなものだと思います。