初学者的问题 MQL5 MT5 MetaTrader 5 - 页 1333

 
Mikhail Tkachev:

谢谢你的回答,你一点也不邪恶)
现在一切都说得通了)
UPD
这个结构也能用了

请注意At()方法的返回结果。如果它返回NULL,你将在关键错误 中崩溃。在访问一个对象的指针之前,检查它是否为NULL

 
Mikhail Tkachev:

已经注意到了)
所以解决方案是声明全局空对象....
如果你事先不知道会有多少人?只要声明 "有保留 "就可以了? :)
P.S. 我在内置帮助中没有找到这种声明对象的方法

很久以前,阿尔乔姆给我写了这个班。我无法详细解释它是如何工作的。但阿特姆会记得,并能解释。下面是这个班级本身

#include <Arrays\ArrayObj.mqh>
/********************************************************************\
|   Класс Новый бар                                                  |
\********************************************************************/
class CNewBar : public CObject
  {
private:
  string            m_symbol;
  ENUM_TIMEFRAMES   m_timeframe;
  datetime          m_time;
  datetime          Time(void);                                       //  Возвращает время нулевого бара
  string            Symbol(void)         { return this.m_symbol;    }
public:
  ENUM_TIMEFRAMES   Timeframe(void)      { return this.m_timeframe; }
  datetime          GetTime(void)        { return this.m_time;      } //  Возвращает время последнего обращения
  bool              IsNewBar(void);                                   //  Основная функция класса

                    CNewBar(const string symbol,const ENUM_TIMEFRAMES timeframe);
                   ~CNewBar(void){;}
  };
//+------------------------------------------------------------------+
//|    Конструктор                                                   |
//+------------------------------------------------------------------+
CNewBar::CNewBar(const string symbol,const ENUM_TIMEFRAMES timeframe) : m_time(0)
  {
   this.m_symbol = symbol;
   this.m_timeframe = (timeframe == PERIOD_CURRENT ? Period() : timeframe);
  }
//+------------------------------------------------------------------+
//| CNewBar Time Возвращает время нулевого бара                      |
//+------------------------------------------------------------------+
datetime CNewBar::Time(void)
  {
   datetime array[1], ret;
   ret = CopyTime(this.m_symbol, this.m_timeframe, 0, 1, array) == 1 ? array[0] : 0;
   return(array[0]);
  }
//+------------------------------------------------------------------+
//| CNewBar IsNewBar Основная функция класса                         |
//+------------------------------------------------------------------+
bool CNewBar::IsNewBar(void)
  {
   datetime tm = this.Time();
   if(tm == 0)
      return false;
   if(tm != this.m_time)
     {
      this.m_time = tm;
      return true;
     }
   return false;
  }

这里是在OnInit()中创建指针的循环。

   for(int i = 0; i < ArraySize(Rates); i++)
     {
       CNewBar* nb = new CNewBar(Rates[i].m_Symbols, timefram);
       if(nb != NULL)
         {
          list_new_bar.Add(nb);
          Print(nb.IsNewBar(), " ***** ", Rates[i].m_Symbols, " ***** ", nb.Time());
         }
     }

并在OnTimer()中

void OnTimer()
{
 int total = list_new_bar.Total();
 for(int i = 0; i < ArraySize(Rates); i++)
  {
   CNewBar* nb = list_new_bar.At(i);
   if(nb == NULL)
    continue;
   bool new_bar = nb.IsNewBar();
   if(new_bar)
    {// и дальше………

ArraySize(Rights)是结构数组的大小,其中列出了要处理的字符。

 
Alexey Viktorov:

Artyom曾经给我写过这个班。我无法详细解释它是如何工作的。但阿尔乔姆会记得,并能解释。好吧,这里就是这个班级本身

这里是在OnInit()中创建指针的循环。

并在OnTimer()中

ArraySize(Rights)是结构数组的大小,其中列出了要处理的字符。

在这里。

for(int i = 0; i < ArraySize(Rates); i++)

我会在总数之前进行--原因很简单,你要从 Rates 数组中读取字符(对吗),创建新的条形类的实例并将它们添加到列表中。

在任何添加错误中,指向新条形类实例的指针列表的大小将与率数组的大小不一致。

一般来说,它必须是这样的。

void OnTimer()
  {
   int total = list_new_bar.Total();
   for(int i = 0; i < total; i++)
   {
   CNewBar* nb = list_new_bar.At(i);
   if(nb == NULL)
      continue;
   if(nb.IsNewBar())
     {// и дальше………

而这也是你需要检查成功加入名单的地方。

   for(int i = 0; i < ArraySize(Rates); i++)
     {
       CNewBar* nb = new CNewBar(Rates[i].m_Symbols, timefram);
       if(nb != NULL)
         {
          list_new_bar.Add(nb);
          Print(nb.IsNewBar(), " ***** ", Rates[i].m_Symbols, " ***** ", nb.Time());
         }
     }

类似这样的事情。

   for(int i = 0; i < ArraySize(Rates); i++)
     {
      CNewBar *nb = new CNewBar(Rates[i].m_Symbols, timefram);
      if(nb==NULL)
         continue;
      if(!list_new_bar.Add(nb))
        {
         delete nb;
         continue;
        }
      Print(nb.IsNewBar(), " ***** ", Rates[i].m_Symbols, " ***** ", nb.Time());
     }
以避免当一个新对象的指针被错误地添加到列表中时的内存泄漏。
 
Artyom Trishkin:

在这里。

我会在总数之前 做--只是因为你从Rates数组中读取字符(对吗),创建新bar类的实例并将它们添加到列表中。

在任何添加错误中,指向新条形类实例的指针列表的大小将与率数组的大小不一致。

一般来说,它必须是这样的。

而这也是你需要检查成功加入名单的地方。

类似这样的事情。

以避免当一个新对象的指针被错误地添加到列表中时的内存泄漏。

谢谢。我知道了,我会把它改成 这样的:))))。

我讨厌继续操作员,并尽量不使用它。只在无望的情况下。

      if(nb==NULL)
         continue;

如何区别于

      if(nb!=NULL)
       {
       }
另一件事是,如果出错时,失败的指针被删除......但即使在这里,我们也可以不用讨厌的继续;只需删除Print()。在调试和试图了解发生了什么的时候需要它,如果在工作中发生一些错误,无论如何我都不会明白出了什么问题......重新安装操作系统比了解日志更容易。


既然我们在讨论这个问题,请告诉我,在不涉及细节的情况下,指针和类变量之间有什么区别,哪个更可取。我可以在互联网上读到一些难以理解的细节。可以说,对我来说,肤浅的理解已经足够了......。

 
Artyom Trishkin:

请注意At()方法的返回结果。如果它返回NULL,你将在关键错误 中崩溃。在访问一个对象的指针之前,要检查它是否为NULL。

Artem,谢谢你的宝贵意见)

 
Alexey Viktorov:

谢谢你。我知道了,我会 这样解决 的......:))

我讨厌"继续 "运算符;并且尽量不使用它。只在无望的情况下。

它如何不同于


循环迭代不会结束,也不会开始新的迭代,但它会进入下一个迭代。逻辑会改变。

 
Alexey Viktorov:

Artyom曾经给我写过这个班。我无法详细解释它是如何工作的。但阿尔乔姆会记得,并能解释。总之,这里就是这个班级本身

//+------------------------------------------------------------------+
//| CNewBar Time Возвращает время нулевого бара                      |
//+------------------------------------------------------------------+
datetime CNewBar::Time(void)
  {
   datetime array[1], ret;
   ret = CopyTime(this.m_symbol, this.m_timeframe, 0, 1, array) == 1 ? array[0] : 0;
   return(array[0]);
 }

阿列克谢,感谢你如此详细的答复。
引用的代码片段中ret变量的目的不清楚...
如果在任何情况下,方法都会返回数组[0],那么它的计算结果是什么?
P.S.
为什么在类方法 中使用这个?我们正在与这个特殊阶层的成员合作...


 
Alexey Viktorov:

谢谢你。我知道了,我会 这样解决 的......:))

我讨厌"继续 "运算符;并且尽量不使用它。只在无望的情况下。

如何区别于

另一件事是,如果当错误发生时,你删除了失败的指针......但在这里,你也可以不恨继续;只是删除Print()。在调试和试图了解发生了什么的时候需要它,如果在工作中发生了一些错误,无论如何我都不会明白出了什么问题......我宁愿重新安装操作系统也不愿了解日志。


既然我们在讨论这个问题,请告诉我们,在不涉及细节的情况下,指针和类变量之间的区别是什么,哪个更合适。我可以在互联网上读到一些难以理解的细节。可以说,对我来说,肤浅的理解已经足够了。

我正在努力摆脱不必要的括号--这样我就不会制造森林和树枝。没有打印,就不需要括号--只需删除对象。

通过新的操作者,你创建了一些物理上位于 "某处 "的机制。新运算符返回这个 "某处 "的地址。而这是你提到这个 "机制 "的唯一方式。
而该机制内的螺栓是一个变量。
 
Valeriy Yastremskiy:

循环的迭代不会结束,也不会开始新的循环,而是会进入下一个If。逻辑会改变。

使之过渡到一个新的周期迭代,在这个周期内是
 
Mikhail Tkachev:

阿列克谢,感谢你如此详细的回答。
在给定的代码片段中,ret变量的目的并不清楚...
如果方法返回数组[0],为什么还要计算呢?


阿列克谢在我给出的代码中重做了一些东西。或者我也错过了--我是 "跪着 "写的,作为一个简单的例子来解释我已经不记得的东西。
原因: