Erros, bugs, perguntas - página 2471

 
Igor Makanu:

Explique porque é que quando crio o CChartObjectLabel não estou a apagar objectos em indicador quando desinicializo neste código:

ao mudar de TF recebo entrada no diário: 2019.05.23 09:49:02.044 tstlabel EURUSD,M30: 2 objectos do tipo CChartObjectLabel à esquerda

se não for comentado no OnInit() a criação de etiquetas de texto (CChartObjectLabel), então tudo funcionará correctamente

Passo um ponteiro à funçãoCreateLabel(), masnãoopossoapagar mais tarde emOnDeinit()

Cria um novo objecto l. E não é apagado.
 
Artyom Trishkin:
É criado um novo objecto l. E não é apagado.

logicamente

Mas o âmbito doCChartObjectLabel,*LabelUP,*LabelDN; as variáveis são globais?

Então posso modificar a variável em qualquer ponto do código?

Eu passo um ponteiro à função CreateLabel(), porque é que crio uma nova cópia?

imho, não está a funcionar correctamente.

HH: Se eu criar objectos no OnInit() e depois trabalhar com eles no CreateLabel() (ou seja, eu crio os objectos separadamente e trabalho com eles por ponteiro), tudo funcionará correctamente - mas não me lembro de um caso noutros compiladores para passar um ponteiro para uma função para criar um novo objecto - um ponteiro, ele é um ponteiro!

 
Igor Makanu:

logicamente

mas o meu alcance é global? - significa que posso modificar uma variável em qualquer parte do meu código ?

Eu passo um ponteiro ao CreateLabel(), porque é que recebo uma nova cópia?

Imho, não funciona correctamente.

Ao reatribuir um ponteiro a um novo objecto, perdemos o objecto anterior para o qual o ponteiro reatribuído apontava.
 
Igor Makanu:

logicamente

Mas o âmbito doCChartObjectLabel,*LabelUP,*LabelDN; as variáveis são globais?

Então posso modificar a variável em qualquer ponto do código?

Eu passo um ponteiro à função CreateLabel(), porque é que crio uma nova cópia?

Imho, não funciona correctamente

novo tem de ser removido. Já existem objectos e indicações para eles.
 
Artyom Trishkin:
Reatribuindo um ponteiro a um novo objecto, perdemos o objecto anterior, que foi apontado pelo ponteiro reatribuído.

não, um ponteiro é um ponteiro, em MQL é um descritor, não é o ponto - mas não é correcto criar uma nova cópia do objecto, isto funciona correctamente agora:

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

mas se seguir a sua lógica, então este código também criará uma cópia do objecto l na função SetLabel() - eu passei um ponteiro, não uma referência?


Artyom Trishkin:
novo deve ser removido. Os objectos já existem e o mesmo acontece com as indicações que lhes são dadas.

a questão não é como resolver o problema, mas porque é que no âmbito global da variávelCChartObjectLabel *LabelUP,*LabelDN;- perdeu o ponteiro!

 
Igor Makanu:

não, um ponteiro é um ponteiro, em MQL é um descritor, não é o ponto - mas não é correcto criar uma nova cópia do objecto, isto funciona correctamente agora:

mas se seguir a sua lógica, então este código também criará uma cópia do objecto l na função SetLabel() - passei um ponteiro, não uma referência?

Não. Aqui l é um parâmetro do método através do qual passamos o ponteiro necessário. Aqui tudo está bem. O ponteiro aqui fica sobre o objecto criado anteriormente. Aqui, não criamos um novo objecto e reatribuímos-lhe o ponteiro com a perda do objecto anterior.
 
Artyom Trishkin:
Não. Aqui l é o parâmetro do método através do qual passamos o ponteiro necessário. Aqui está tudo bem. O ponteiro aqui fica sobre o objecto criado anteriormente. Aqui, não criamos um novo objecto e reatribuímos-lhe o ponteiro com a perda do objecto anterior.

continua a não funcionar correctamente

estes "indicadores" em MQL são feitos para funcionar no âmbito da classe, não quero criar uma classe, declaro um indicador global e depois passo-o a qualquer função, e o facto de nesta função criar um descritor do objecto não é a razão para destruir o objecto ao sair do âmbito local da função

Estou um pouco ocupado neste momento, mas preciso de fazer exemplos de teste sem gráficos - penso que o mesmo acontecerá se introduzir a função com um ponteiro com o valor POINTER_INVALID , por referência, tudo funcionará correctamente, mas parece que não pode passar um ponteiro com o valor POINTER_INVALID por referência - haverá um erro ao aceder ao ponteiro

 
Igor Makanu:

tudo não funciona correctamente de qualquer maneira

estes "indicadores" em MQL são feitos para funcionar no âmbito da classe. não quero criar uma classe, perfuro e declaro um indicador global, depois passo-o para qualquer função e o facto de eu criar um manípulo de objecto nesta função não é a razão para destruir um objecto ao deixar o âmbito local de uma função

Penso que será o mesmo problema, se entrar com o valor POINTER_INVALID nesta função, sairá com o mesmo valor POINTER_INVALID , por referência, tudo funcionará correctamente, mas parece que não pode passar um valor POINTER_INVALID nesta função - haverá um erro ao aceder ao ponteiro

Exactamente o objecto não está destruído. Depois de um novo objecto ser criado dentro do método, já temos dois objectos. E há apenas um ponteiro - foi passado para o método como parâmetro formal. Assim, perdemos o ponteiro para um dos objectos.
 

Fiquei surpreendido ao descobrir que era possível declarar o typedef com um ponteiro para uma função modelo.
No entanto, a felicidade não durou muito tempo.

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   
}


Será que o typedef com um ponteiro para uma função modelo é uma característica planeada?

 
Mais um insecto no jardim do typedefef:
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);
}

Ao trabalhar com typedef, a utilização de uma função de modelo com especialização explícita não gera código para esse modelo
Razão: