Questions on OOP in MQL5 - page 35

 
Roman:

If the object has completed its task, why keep it in memory?
Won't there be a memory leak?

It will, especially if it is not deleted even in OnDeinit.
You don't have to store it in memory, if you really don't need it anymore. But more often it happens that an object is created and used at one iteration... And then on the second iteration... And so on. And then, under certain conditions, another object of the same class is created, and you already work with two or more objects of this class, each of which is needed throughout the life of the EA.

 
BlackTomcat:

It will occur, especially if it is not deleted even in OnDeinit.
You don't have to store it in memory, if you really don't need it anymore. But more often it happens that an object is created and used at one iteration... And then on the second iteration... And so on. And then, under certain conditions, another object of the same class is created, and you already work with two or more objects of this class, each of which is needed throughout the life of the EA.

So you want to say that a controlled memory leak is better than recreating objects?
That is, saving time, in exchange for controlled daemons?
It's dangerous not to lose them later.

 

wrote using the templatehttps://www.mql5.com/ru/forum/85652/page24#comment_13054686 of the expert

quite a flexible template, allows adding different "pluses" in "2 clicks" and the code turns out readable and logical, but... I got back to some discussed paradigm that a good class, well, it shouldn't have static methods

It sounds nice in theory but in practice... Not in my opinion, at least for MQL-problems, imho.

According to the template, the EA class was written and one public method is started in OnTick(). But during initialization of the EA, I want to check if there are open orders and intercept them:

1. write a function in the OnTick() below which if it finds an open order via the wizard, it creates an EA object; if no order is found, the EA object is initialized according to the basic logic - the EA object is created only in trading time and implements the logic of the TS in the future

2. Write a static class in EA, which implements the items 1


Essentially the items 1 and 2 are the same, the difference is that in step 1, I add a function that would make sense only during the initialization of the EA (the first run), but imho, it overloads the code - one function will be called once for the entire execution of the program!

if you make a static method ( pp.2 ), then it will be logical and readable - the method is needed only for initialization and defines the moment, when EA object should be created - you should pass to this method only magic number.


To my mind to forbid to use static methods when it's convenient... to put it mildly wrong!

 
Igor Makanu:

Static methods differ from functions only in their scope.


This practice is dangerous

input int inInput = 0;

const bool Init = EventSetTimer(1);

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


If you change the input while the EA is running, the Input will not change.

Accordingly, it is fraught with

input long inMagic = 0;

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

If you change input while EA is running, Input will not change.

I'm aware of that, and in my TS you cannot change input parameters while EA is working, the run time is separate from the logic of TS

My question is purely theoretical, I don't want to overload the code, so I'm looking for possibility to restore the TS after crashing somewhere, so far I see it like this:

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

It makes more sense to shove this logic into the constructor.

 
fxsaber:

Static methods differ from functions only in their scope.

Incorrect. They also have access to non-public members and methods of the class.
 
TheXpert:
incorrect. also access to non-public members and methods of the class.

There is a terminological misunderstanding here. "Area of visibility" is not just about who sees the method. But also what he himself sees.

 
fxsaber:

There is a terminological misunderstanding here.

After all, visibility and access are different concepts and it is best not to mix them up
 
fxsaber:

It makes more sense to put this logic in the constructor.

Yes, that's a better solution! So there is one less method

That's how it should be:

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:
after all, visibility and access are different concepts and it is best not to mix them up
that's why I have a question, where would I put a way to detect that the last run was crashing, now my code structure is compact, everything is clearly following the pattern I showed above
Reason: