Ошибки, баги, вопросы - страница 2471

 
Igor Makanu:

Обьясните почему при создании CChartObjectLabel у меня не удаляются обекты в индикаторе при деинициализации в таком коде:

при переключении ТФ получаю запись в журнале: 2019.05.23 09:49:02.044 tstlabel EURUSD,M30: 2 objects of type CChartObjectLabel left

если раскомментировать в OnInit() создание текстовых меток ( CChartObjectLabel ), то все будет корректно работать

в ф-цию CreateLabel() передаю указатель, а удалить его потом в OnDeinit() почему то не удается

Создаётся новый объект l. И он-то не удаляется.
 
Artyom Trishkin:
Создаётся новый объект l. И он-то не удаляется.

логично

но область видимости переменных CChartObjectLabel *LabelUP,*LabelDN; у меня глобальная?

значит я могу в любом участке кода произвести модификацию переменой ?

я передаю в ф-цию CreateLabel() указатель, почему у меня создается новая копия?

имхо, не корректно все это работает

ЗЫ: если создать обьекты в OnInit() и затем произвести работу с ними в CreateLabel() (т.е. создаю обьекты отдельно, а работаю с ними по указателю) то все будет работать корректно - но не припомню случая в других компиляторах чтобы передача указателя в ф-цию создавала новый объект - указатель он и в Африке указатель!

 
Igor Makanu:

логично

но область видимости переменных у меня глобальная? - значит я могу в любом участке кода произвести модификацию переменой ?

я передаю в ф-цию CreateLabel() указатель, почему у меня создается новая копия?

имхо, не корректно все это работает

Переназначая указатель на новый объект, теряем предыдущий объект, на который указывал переназначенный указатель . 
 
Igor Makanu:

логично

но область видимости переменных CChartObjectLabel *LabelUP,*LabelDN; у меня глобальная?

значит я могу в любом участке кода произвести модификацию переменой ?

я передаю в ф-цию CreateLabel() указатель, почему у меня создается новая копия?

имхо, не корректно все это работает

new надо убирать. Объекты же есть уже, и указатели на них. 
 
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);
  }
//+------------------------------------------------------------------+

но если следовать твоей логике, то и в этом коде будет создана копия обьекта l в ф-ции SetLabel() -  я же указатель передал, а не ссылку?


Artyom Trishkin:
new надо убирать. Объекты же есть уже, и указатели на них. 

вопрос не как решить проблему, а почему при глобальной области видимости переменной CChartObjectLabel *LabelUP,*LabelDN; - потерялся указатель!

 
Igor Makanu:

нет, указатель это указатель, в MQL он дескриптор, не суть - но новую копию обьекта создавать не корректно это, вот так сейчас работает корректно:

но если следовать твоей логике, то и в этом коде будет создана копия обьекта l в ф-ции SetLabel() -  я же указатель передал, а не ссылку?

Нет. Здесь 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:
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 использование шаблонной функции с явной специализацией не вызывает генерацию кода этой шаблонной
Причина обращения: