Perguntas sobre OOP em MQL5 - página 35

 
Roman:

Se o objeto completou sua tarefa, por que guardá-lo na memória?
Não haverá um vazamento de memória?

Ela o fará, especialmente se não for excluída mesmo no OnDeinit.
Não é necessário armazená-lo na memória, se você realmente não precisar mais dele. Mas acontece com mais freqüência que um objeto é criado e utilizado em uma iteração. E depois, na segunda iteração... E assim por diante. E então, sob certas condições, outro objeto da mesma classe é criado, e você já trabalha com dois ou mais objetos desta classe, cada um dos quais é necessário durante toda a vida da EA.

 
BlackTomcat:

Isso ocorrerá, especialmente se não for excluído mesmo no OnDeinit.
Não é necessário armazená-lo na memória, se você realmente não precisar mais dele. Mas acontece com mais freqüência que um objeto é criado e utilizado em uma iteração. E depois, na segunda iteração... E assim por diante. E então, sob certas condições, outro objeto da mesma classe é criado, e você já trabalha com dois ou mais objetos desta classe, cada um dos quais é necessário durante toda a vida da EA.

Então você quer dizer que um vazamento controlado de memória é melhor do que recriar objetos?
Isto é, economizando tempo, em troca de demônios controlados?
É perigoso não perdê-los mais tarde.

 

escreveu usando o modelohttps://www.mql5.com/ru/forum/85652/page24#comment_13054686 do especialista

um modelo bastante flexível, permite adicionar diferentes "valias" em "2 cliques" e o código se torna legível e lógico, mas... Voltei a um paradigma discutido de que uma boa classe, bem, não deveria ter métodos estáticos

Parece bom na teoria, mas na prática... Não em minha opinião, pelo menos para os problemas de MQL, imho.

De acordo com o modelo, a classe EA foi escrita e um método público é iniciado em OnTick(). Mas durante a inicialização da EA, eu quero verificar se há ordens abertas e interceptá-las:

1. escreva uma função no OnTick() abaixo da qual, se encontrar uma ordem aberta através do assistente, ele cria um objeto EA; se nenhuma ordem for encontrada, o objeto EA é inicializado de acordo com a lógica básica - o objeto EA é criado somente em tempo de negociação e implementa a lógica do TS no futuro

2. escreva uma classe estática na EA, que implementa os itens 1


Essencialmente os itens 1 e 2 são os mesmos, a diferença é que no passo 1, eu adiciono uma função que faria sentido somente durante a inicialização da EA (a primeira execução), mas imho, ela sobrecarrega o código - uma função será chamada uma vez para toda a execução do programa!

se você fizer um método estático ( pp.2 ), então ele será lógico e legível - o método é necessário apenas para inicialização e define o momento, quando o objeto EA deve ser criado - você deve enviar a este método apenas um número mágico.


A meu ver, proibir o uso de métodos estáticos quando for conveniente. para colocar as coisas levemente erradas!

 
Igor Makanu:

Os métodos estáticos diferem das funções apenas em seu escopo.


Esta prática é perigosa

input int inInput = 0;

const bool Init = EventSetTimer(1);

void OnTimer()
{
  static int Input = inInput;
  
  Print(Input);
}


Se você alterar a entrada enquanto o EA estiver em funcionamento, a Entrada não mudará.

Por conseguinte, está repleta de

input long inMagic = 0;

void OnTick()
{
  static ORDER Orders[]; // Список ордеров по мэджику или что-то подобное, зависящая от входных.
}
 
fxsaber:

Se você mudar a entrada enquanto a EA estiver em funcionamento, a entrada não mudará.

Estou ciente disso, e em meu TS você não pode alterar os parâmetros de entrada enquanto a EA está trabalhando, o tempo de execução é separado da lógica do TS

Minha pergunta é puramente teórica, eu não quero sobrecarregar o código, então estou procurando a possibilidade de restaurar o TS depois de cair em algum lugar, até agora eu o vejo assim:

input int EAMagicNumber = 12345;
class CEA
{
public:
   static bool       NeedRecovery(int magic_)            {   return(true);    }
   bool              Recovery(int magic_,int inputparam) {   return(true);    }
                     CEA()                               {                    }
                     CEA(int inputparam)                 {                    }
                    ~CEA()                               {                    }
};

CEA *ea;

void OnStart()
{
   if(CheckPointer(ea)==POINTER_INVALID)
   {
      if(CEA::NeedRecovery(EAMagicNumber))   //если нашли открытые ордера с магиком
      {
         ea = new CEA();         // создали объект
         ea.Recovery(EAMagicNumber,11111);   // запустили восстановление ТС
      }else ea = new CEA(2222222);           //обычный запуск
   }
 
Igor Makanu

Faz mais sentido empurrar esta lógica para dentro do construtor.

 
fxsaber:

Os métodos estáticos diferem das funções apenas em seu escopo.

Incorreto. Eles também têm acesso a membros não públicos e métodos da classe.
 
TheXpert:
incorreto. também acesso a membros não públicos e métodos da classe.

Há aqui um mal-entendido terminológico. "Área de visibilidade" não se trata apenas de quem vê o método. Mas também o que ele mesmo vê.

 
fxsaber:

Há aqui um mal-entendido terminológico.

Afinal de contas, visibilidade e acesso são conceitos diferentes e é melhor não misturá-los
 
fxsaber:

Faz mais sentido colocar esta lógica no construtor.

Sim, essa é uma solução melhor! Portanto, há um método a menos

É assim que deve ser:

input int EAMagicNumber = 12345;
class CEA
{
public:
   static bool       NeedRecovery(int magic_)            {   return(true);    }  //тут проверки
                     CEA(int magic_)                     {                    }  //это обычный запуск если все ОК
                     CEA(int magic_, int recoveryparam)  {                    }  //тут аварийное восстановление
                    ~CEA()                               {                    } };

CEA *ea;

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnStart()
{  if(CheckPointer(ea)==POINTER_INVALID)
   {  if(CEA::NeedRecovery(EAMagicNumber))   //если нашли откртые ордера с магиком
      {  
         ea = new CEA(EAMagicNumber,11111);  // запустили востановление ТС
      }
      else ea = new CEA(EAMagicNumber);      //обычный запуск
   } 
}
TheXpert:
afinal, visibilidade e acesso são conceitos diferentes e é melhor não misturá-los
é por isso que tenho uma pergunta, onde eu colocaria uma forma de detectar que a última corrida estava se chocando, agora minha estrutura de código é compacta, tudo está claramente seguindo o padrão que mostrei acima