错误、漏洞、问题 - 页 2471

 
Igor Makanu:

解释一下为什么当我创建CChartObjectLabel时,在这段代码中,在去初始化时没有删除指标中的对象。

当切换TF时,我得到了日志记录:2019.05.23 09:49:02.044 tstlabel EURUSD,M30: 剩下2个CChartObjectLabel类型的对象。

如果在OnInit()中取消文本标签的创建(CChartObjectLabel),那么一切都会正常工作。

CreateLabel()函数传递了一个 指针,但我不能在之后OnDeinit()中删除它

它创建了一个新的对象l。而且没有被删除。
 
Artyom Trishkin:
一个新的l对象被创建。而且,它没有被删除。

在逻辑上

但是CChartObjectLabel *LabelUP,*LabelDN; 变量的范围 是全局的?

所以我可以在代码中的任何一点上修改这个变量?

我向CreateLabel()函数传递了一个指针,为什么会创建一个新的副本?

我认为,它没有正常工作。

HH:如果我在OnInit()中创建对象,然后在CreateLabel()中处理它们(也就是说,我分别创建对象并通过指针处理它们),一切都会正常工作--但我不记得在其他编译器中出现过向函数传递指针以创建新对象的情况--指针,他就是一个指针!我不知道。

 
Igor Makanu:

在逻辑上

但我的范围 是全球性的?- 这意味着我可以在我的代码的任何部分修改一个变量?

我向CreateLabel()传递了一个指针,为什么会得到一个新的副本?

我认为,它不能正确工作。

通过重新分配一个指针到一个新的对象,我们失去了重新分配的指针所指向的前一个对象。
 
Igor Makanu:

在逻辑上

但是CChartObjectLabel *LabelUP,*LabelDN; 变量的范围 是全局的?

所以我可以在代码中的任何一点上修改这个变量?

我向CreateLabel()函数传递了一个指针,为什么会创建一个新的副本?

我认为,它不能正确工作

新的必须被删除。已经有了对象和指向它们的指针。
 
Artyom Trishkin:
将一个指针重新赋值给一个新的对象,我们就会失去之前的对象,这个对象是由重新赋值的指针指向的。

不,指针就是指针,在MQL中,它是一个描述符,而不是点 - 但创建一个新的对象副本是不正确的,现在这个工作是正确的。

//+------------------------------------------------------------------+
//|                                                         test.mq4 |
//|                        Copyright 2018, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link      "https://www.mql5.com/ru/users/igorm"
#property version   "1.00"
#property strict
#property indicator_separate_window
#include <ChartObjects\ChartObjectsTxtControls.mqh>
CChartObjectLabel *LabelUP,*LabelDN;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
   LabelUP=new CChartObjectLabel;
   LabelDN=new CChartObjectLabel;
   SetLabel(LabelUP,"LabelUP",0);
   SetLabel(LabelDN,"LabelDN",25);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   delete LabelUP;
   delete LabelDN;
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
   return(rates_total);

  }
//+------------------------------------------------------------------+
void SetLabel(CChartObjectLabel *l,string name,int y)
  {
   l.Create(0,name,ChartWindowFind(),0,y);
   l.Color(clrYellow);
   l.FontSize(14);
   l.Description(name);
  }
//+------------------------------------------------------------------+

但是如果你按照你的逻辑,那么这段代码也会在SetLabel()函数中创建一个对象l的副本-- 我传递的是一个指针,而不是一个引用?


阿尔乔姆-特里什金
新的应该被删除。这些对象已经存在,它们的指针也已经存在。

问题不是如何解决问题,而是为什么在全局范围 内的变量CChartObjectLabel *LabelUP,*LabelDN;--丢失了指针!

 
Igor Makanu:

不,指针就是指针,在MQL中,它是一个描述符,而不是点 - 但创建一个新的对象副本是不正确的,现在这个工作是正确的。

但如果按照你的逻辑,那么这段代码也会在函数SetLabel()中创建一个对象l的副本-- 我传递了一个指针,而不是一个引用?

不,这里l是方法的一个参数,我们通过它传递所需的指针。这里一切都很好。这里的指针保持在先前创建的对象 上。在这里,我们不创建一个新的对象,并在失去前一个对象的情况下重新分配指针给它。
 
Artyom Trishkin:
不,这里l是方法参数,我们通过它传递必要的指针。这里一切都很好。这里的指针保持在先前创建的对象 上。在这里,我们不创建一个新的对象,并在失去前一个对象的情况下重新分配指针给它。

还是不能正常工作

MQL中的这些 "指针 "是在类的范围内工作的,我不想创建一个类,我声明一个全局指针,然后把它传递给任何函数,而且在这个函数中我创建了一个对象的描述符,这不是在退出函数的局部范围时销毁该对象的理由。

我现在有点忙,但我需要在没有图形的情况下做测试例子--我想如果你用一个带POINTER_INVALID值的指针进入函数,也会发生同样的事情,你会用同样的POINTER_INVALID退出,通过引用,一切都会正常工作,但似乎你不能通过引用传递一个带POINTER_INVALID的指针--访问这个指针会有一个错误。

 
Igor Makanu:

反正一切都不能正常工作

MQL中的这些 "指针 "是在类的范围内工作的,我不想创建一个类,我只是在全局范围内钻研并声明一个指针,然后把它传递给任何函数,我在这个函数中创建一个对象句柄的事实不是在退出函数的局部范围时销毁该对象的理由。

我认为这将是同样的问题,如果你在这个函数中以POINTER_INVALID值进入,你将以同样的POINTER_INVALID值退出,通过引用,一切都将正常工作,但似乎你不能在这个函数中传递一个POINTER_INVALID值--在访问指针时将出现一个错误。

确切地说,该对象没有被销毁。在方法里面创建了一个新的对象之后,我们已经有了两个对象。而且只有一个指针--它是作为一个正式参数传递 给方法的。因此,我们失去了指向其中一个对象的指针。
 

我惊讶地发现,可以用一个指向模板函数的指针来声明typedef。
然而,这种幸福并没有持续多久。

template<typename T>
typedef bool (* callback)(T &);

template<typename T>
bool ff(T &){
   return true;
}

bool ff(int &){
   return true;
}


void OnStart(){
   int a;
   ff(a);
   
   callback<int> f_ptr_0 = ff;     //'<' - unexpected token     
   callback f_ptr_1 = ff;          //'ff' - function must have a body   
   callback f_ptr_2 = ff<int>;     //'ff<int>' - cannot resolve function address  //'ff<int>' - type mismatch   
}


带有指向模板函数的指针的typedef是计划中的功能吗?

 
在typedef花园中还有一个bug。
typedef void (* callback)(int &);

template<typename T>
void ff(T &){}


void OnStart(){
   int a = 0;
   //ff(a);                     //  если раскомментировать, то работает
   
   callback f_ptr = ff<int>;    //  'ff<int>' - function must have a body
   f_ptr(a);
}

当使用typedef工作时,使用具有明确专业化的模板函数不会为该模板生成代码
原因: