错误、漏洞、问题 - 页 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上进行测试,最近在这个主题中以压缩版的形式发布,我想。

 
Renat Fatkhullin:

不要忘记更新到最新的构建。

是的,旧的建设。

雷纳特-法特库林

这是正确的,你不能从下往上开,只能从上往下开。这是为了安全起见。

你应该把这个擦掉,它有误导性,并且直接与dynamic_cast的功能相抵触。
 
Комбинатор:

是的,旧的建设。

你把这个擦掉,它有误导性,并且直接与dynamic_cast的功能相抵触

作为提出的CLASS1->CLASS2头对头铸造例子的一部分,你说对了。这就是大多数时候人们头脑中的那种铸造。

另外,"你不能从下往上投,只能从上往下投 "才是dynamic_cast安全检查的核心所在。

那些知道自己在做什么的人都明白dynamic_cast的本质。

 
Renat Fatkhullin:

不要忘记更新到最新的构建。我目前正在1598上进行测试,最近在这个主题中,我想是以压缩包的形式发布的。

编译器和执行器位于哪个exe文件中?

现在,MT4b1080正在运行MEb1599。请解释metaeditor.exe和terminal.exe是做什么的。

 
fxsaber:

编译器和执行器位于哪个exe文件中?

MT4b1080现在正在运行MEb1599。请解释metaeditor.exe和terminal.exe是做什么的。

两个平台的编译器是一样的。它在metaeditor.exe中。
 
Renat Fatkhullin:
两个平台的编译器是一样的。它在metaeditor.exe中。
而在终端.exe中的执行器,检查同样的dynamic_cast ?
 
fxsaber:
而在终端.exe中的执行器,检查同样的dynamic_cast ?
当然了
 
Renat Fatkhullin:
另一个这样的问题

关于交易、自动交易系统和交易策略测试的论坛

虫子、虫子、问题

fxsaber, 2017.05.11 13:26

为什么是EX5这样的代码
void OnStart() {}

它有5kb重吗?