错误、漏洞、问题 - 页 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:

你能不能让它更简单、更优雅--没有不必要的括号和指针--(而且它的编译没有奇怪的错误))))

你的例子在我的情况下是行不通的,我的对象是动态创建的,我甚至没有给它们分配一个名字,而你的例子使用了一个指针式的名字,我这样试了一下,编译器不允许通过: '[' - 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;
  }
//+------------------------------------------------------------------+

SZZ:我已经开始有点理解你的建议了,但还是没有结果,我可以不用dynamic_cast <>,加入*CObject 字段,理论上应该是这样的。

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

我认为这将比你的例子中的dynamic_cast <>工作得更快一些--意义是一样的。

 
Igor Makanu:

在MQL中是否可以取消对*CObject指针的引用?

我尝试了不同的变体,这里有一个测试脚本,我在链接列表中添加了3个Myclass元素,然后改变CMyclass字段的值,它起作用了。

我可以修改动态创建的CMyclass元素的字段,而不需要中间的指针CMyclass *result吗?

像这样:(CMyclass *)(base.GetCurrentNode()).x = 99。

PS:我怀疑你需要使用typedef,但到目前为止还没有成功。

你所写的只是一种隐性的使用。

result=base.GetCurrentNode();

即这样一个匿名指针,但本质上只是语法上的糖。MQL中几乎没有糖,所以不能这样做。但是我应该注意到,向后裔的投递 是在没有任何检查和转换的情况下进行的,所以不清楚为什么你不喜欢用指针进行明确的工作。

 
Igor Makanu:

ZS:有点开始理解你的建议了,但还是没有结果,你可以不用dynamic_cast <>,添加一个字段*CObject,理论上,应该是这样的。

我认为这将比你的例子中的dynamic_cast <>工作得更快一些--意义是一样的。

你可以不用单独的字段,就像上面建议的那样,但只能通过在运算符中包装来实现。

有一个小小的区别。如果突然发现有一个对象没有被投到myclass中,如果没有dynamic_cast,就会出现执行错误,而有了它,你会得到NULL的回报。如果你立即用.x来解决,无论如何都会引起运行时错误,所以不必麻烦=)))

如果我们按照医生的吩咐去做,我们应该返回类似于为处理错误而创建的特殊类实例的东西 ))))

P.S. 我最近检查了dynamic_casta的速度,与通常的铸造相比,在类与预期类相等的情况下,速度几乎相同。

P.S.S. 在任何情况下,for's在那里看起来相当悲哀--当处理列表时,你应该使用for each这样的循环(像我的循环)。
 
Igor Makanu:

没有通过编译器:'[' - 预计名称 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;
  }
//+------------------------------------------------------------------+

...

我们用这个包装袋到底得到了什么?在绝对没有必要的情况下,一个不必要的动态广播?包装器本身有一个明确的转换到CMyClass的过程。也就是说,它有0%的工作量,而代码却更复杂(索引引用操作符被用作被传递的类的显式投掷操作符--嗯,这一点也不明显)。

 
Ilya Malev:
P.S.S. 在任何情况下,for's看起来相当悲哀--在处理列表时,你应该使用for each这样的循环(像我的循环)。

对不起,但这是愚蠢的。

 
Vasiliy Sokolov:

你所写的只是一种隐性的使用。

即这样一个匿名指针,但基本上只是语法上的糖。MQL中几乎没有糖,所以你不能这样做。但我应该指出,向后裔的投递 是在没有任何检查和转换的情况下进行的,所以不清楚为什么对指针的明确工作会如此令人讨厌。

是的,我明白了,在使用指针时,我仍然对MQL的语法感到困惑,它似乎与标准的C++相同,但我经常感到困惑,既不能直接写东西,也不能正确阅读来自МТ.... 标准交付的库的代码。我把我的头发都拔光了!...但还是在.Opera上!))))- 反正我会想出办法的;)


Ilya Malev:

有一个区别,一个小的区别。如果碰巧有一个对象没有转换为myclass,如果没有dynamic_cast,将会出现执行错误,而有了它,你将会得到NULL的回报。如果你立即用.x来解决这个问题,无论如何都会导致一个错误。

我理解这一切,这不是一个小的区别,我要真诚地说,专业程序员的代码与业余程序员的区别就在于此--在检查关键错误方面.....。尽管随着现代编程语言的发展,它已经为较差的程序员使用try except finally等进行了简化;)

 
Vasiliy Sokolov:

我很抱歉,但这是愚蠢的。

哦,拜托。

 
Igor Makanu:

是的,我都明白,在MQL中处理指针时,我搞不清楚语法,似乎与标准C++相同,但我经常感到困惑,既不能直接写东西,也不能从标准MT....,正确阅读同一库的代码。我把我的头发都拔光了!...但还是在.Opera上!))))- 想通了吧;)

在MQL的情况下,以C++为参考点是行不通的 :)MQL中不可能的东西的数量比 "兼容 "结构的数量大得多。我认为,MQL更像是一个非常截断的C#,完全缺乏句法糖。