Errores, fallos, preguntas - página 2471

 
Igor Makanu:

Explica por qué cuando creo CChartObjectLabel no estoy borrando los objetos en el indicador cuando se desinicializa en este código:

al cambiar de TF obtengo el registro en el diario: 2019.05.23 09:49:02.044 tstlabel EURUSD,M30: quedan 2 objetos de tipo CChartObjectLabel

si se descomenta en OnInit() la creación de etiquetas de texto (CChartObjectLabel), entonces todo funcionará correctamente

Paso un puntero a la funciónCreateLabel(), perono puedoborrarlo después enOnDeinit()

Crea un nuevo objeto l. Y no se borra.
 
Artyom Trishkin:
Se crea un nuevo objeto l. Y no se borra.

lógicamente

¿Pero el alcance de las variablesCChartObjectLabel *LabelUP,*LabelDN; es global?

¿Así que puedo modificar la variable en cualquier punto del código?

Paso un puntero a la función CreateLabel(), ¿por qué creo una nueva copia?

imho, no está funcionando correctamente.

HH: Si creo los objetos en OnInit() y luego trabajo con ellos en CreateLabel() (es decir, creo los objetos por separado y trabajo con ellos por puntero), todo funcionará correctamente - pero no recuerdo un caso en otros compiladores de pasar un puntero a una función para crear un nuevo objeto - ¡un puntero, es un puntero!

 
Igor Makanu:

lógicamente

¿pero mi alcance es global? - ¿significa que puedo modificar una variable en cualquier parte de mi código?

Paso un puntero a CreateLabel(), ¿por qué obtengo una nueva copia?

En mi opinión, no funciona correctamente.

Al reasignar un puntero a un nuevo objeto, perdemos el objeto anterior al que apuntaba el puntero reasignado.
 
Igor Makanu:

lógicamente

¿Pero el alcance de las variablesCChartObjectLabel *LabelUP,*LabelDN; es global?

¿Así que puedo modificar la variable en cualquier punto del código?

Paso un puntero a la función CreateLabel(), ¿por qué creo una nueva copia?

En mi opinión, no funciona correctamente

nuevo tiene que ser eliminado. Ya hay objetos y punteros a ellos.
 
Artyom Trishkin:
Al reasignar un puntero a un nuevo objeto, perdemos el objeto anterior, al que apuntaba el puntero reasignado.

no, un puntero es un puntero, en MQL es un descriptor, no el punto - pero no es correcto crear una nueva copia del objeto, esto funciona correctamente ahora:

//+------------------------------------------------------------------+
//|                                                         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);
  }
//+------------------------------------------------------------------+

pero si sigues tu lógica, entonces este código también creará una copia del objeto l en la función SetLabel() - pasé un puntero, no una referencia?


Artyom Trishkin:
nuevo debe ser eliminado. Los objetos ya existen y los punteros a ellos también.

la cuestión no es cómo resolver el problema, sino por qué en el ámbito global de la variableCChartObjectLabel *LabelUP,*LabelDN;- ¡se pierde el puntero!

 
Igor Makanu:

no, un puntero es un puntero, en MQL es un descriptor, no el punto - pero no es correcto crear una nueva copia del objeto, esto funciona correctamente ahora:

pero si sigues tu lógica, entonces este código también creará una copia del objeto l en la función SetLabel() - pasé un puntero, no una referencia?

No. Aquí l es un parámetro del método por el que pasamos el puntero necesario. Todo está bien aquí. El puntero aquí permanece en el objeto creado anteriormente. Aquí no creamos un nuevo objeto y reasignamos el puntero a él con la pérdida del objeto anterior.
 
Artyom Trishkin:
No. Aquí l es el parámetro del método por el que pasamos el puntero necesario. Todo está bien aquí. El puntero aquí permanece en el objeto creado anteriormente. Aquí no creamos un nuevo objeto y reasignamos el puntero a él con la pérdida del objeto anterior.

sigue sin funcionar correctamente

estos "punteros" en MQL están hechos para trabajar en el ámbito de la clase, no quiero crear una clase, declaro un puntero global y luego lo paso a cualquier función, y el hecho de que en esta función cree un descriptor del objeto no es motivo para destruir el objeto al salir del ámbito local de la función

Estoy un poco ocupado ahora mismo, pero necesito hacer ejemplos de prueba sin gráficos - creo que lo mismo ocurrirá si entras en la función con un puntero con valor POINTER_INVALID, saldrás con el mismo POINTER_INVALID , por referencia, todo funcionará correctamente, pero parece que no puedes pasar un puntero con POINTER_INVALID por referencia - habrá un error al acceder al puntero

 
Igor Makanu:

todo no funciona correctamente de todas formas

estos "punteros" en MQL están hechos para trabajar en el ámbito de la clase, no quiero crear una clase, simplemente perforo y declaro un puntero en el ámbito global, luego lo paso a cualquier función y el hecho de crear un descriptor de objeto en esta función no es la razón para destruir el objeto al salir del ámbito local de la función

Creo que será el mismo problema, si entras con el valor POINTER_INVALID en esta función, saldrás con el mismo valor POINTER_INVALID , por referencia, todo funcionará correctamente, pero por referencia no puedes pasar un puntero con POINTER_INVALID - se producirá un error de acceso al puntero.

Exactamente el objeto no se destruye. Después de crear un nuevo objeto dentro del método, ya tenemos dos objetos. Y sólo hay un puntero - se pasó al método como un parámetro formal. Así, perdemos el puntero a uno de los objetos.
 

Me sorprendió descubrir que era posible declarar un typedef con un puntero a una función de plantilla.
Sin embargo, la felicidad no duró mucho.

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   
}


¿Está prevista la inclusión de un typedef con un puntero a una función de plantilla?

 
Un error más en el jardín 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);
}

Cuando se trabaja con typedef, el uso de una función de plantilla con especialización explícita no genera código para esa plantilla
Razón de la queja: