Вопросы по ООП в MQL5 - страница 35

 
Roman:

Если объект выполнил свою задачу, зачем его держать в памяти?
Не возникнет ли утечка памяти?

Возникнет, особенно если его даже в OnDeinit не удалить.
В памяти его можно не хранить, если он действительно больше не нужен. Но чаще бывает так, что объект создаётся и используется на одной итерации... А потом на второй... И так далее. А потом при определённых условиях создаётся ещё один объект этого же класса, и ты работаешь уже с двумя или несколькими объектами этого класса, каждый из которых необходим на протяжении всего срока работы советника.

 
BlackTomcat:

Возникнет, особенно если его даже в OnDeinit не удалить.
В памяти его можно не хранить, если он действительно больше не нужен. Но чаще бывает так, что объект создаётся и используется на одной итерации... А потом на второй... И так далее. А потом при определённых условиях создаётся ещё один объект этого же класса, и ты работаешь уже с двумя или несколькими объектами этого класса, каждый из которых необходим на протяжении всего срока работы советника.

То есть вы хотите сказать, что контролируемая утечка памяти, лучше чем пересоздание объектов?
То есть экономя времени, в обмен на контролируемых демонов?
Опасно, как бы не потерять их потом.

 

написал по шаблону https://www.mql5.com/ru/forum/85652/page24#comment_13054686 эксперта

довольно гибкий шаблон, позволяет в "2 клика" добавлять разные "плюшки" и код получается читаемым и логичным, но... опять вернулся к обсуждаемой некой парадигме, что хороший класс ну вот не должен иметь статических методов

в теории звучит красиво, на практике... по моему никак, по крайней мере для задач MQL, имхо

По шаблону написан класс EA, в OnTick() запускается один публичный метод, но при инициализации EA нужно проверить есть ли открытые ордера и подхватить их, вижу 2 способа:

1. написать функцию в ниже OnTick() которая найдя по магику открытые ордера создаст как обычно обьект EA, если не нашел ордера то соответственно инициализируем по основной логике - обьект ЕА создается только в торговое время и реализует в дальнейшем логику ТС

2. написать статический класс в EA , который сделает пп.1


по сути пп 1 и 2 одно и то же, с разницей что в пп.1  добавлю функцию которая будет иметь смысл только при инициализации эксперта (первый запуск), но имхо, это загромождает код - одна функция и вызываться будет один раз за все выполнение программы!

если делать статический метод ( пп.2 ), то имхо все логично и читаемо будет, метод нужен только для инициализации и определяет лишь момент когда нужно создать обьект ЕА - в этот метод передать нужно только магик-номер, лаконично довольно


по моему запрещать себе использовать статические методы когда это удобно... ну мягко говоря не правильно!

 
Igor Makanu:

Статические метода отличаются от функций только областью видимости.


Такая практика опасна

input int inInput = 0;

const bool Init = EventSetTimer(1);

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


При изменении входного во время работы советника Input не поменяется.

Соответственно, чревато такое

input long inMagic = 0;

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

При изменении входного во время работы советника Input не поменяется.

да я в курсе этого, да и по моей ТС как раз и нельзя менять input параметры во время работы ЕА, время работы отдельно считается от логики ТС 

тут мой вопрос чисто теоретический, не хочу загромождать код, поэтому вот и ищу возможность восстановления ТС после аварийного завершения куда то воткнуть, пока вижу так:

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

Логичнее эту логику в конструктор запихать.

 
fxsaber:

Статические метода отличаются от функций только областью видимости.

неверно. еще доступом к непубличным членам и методам класса.
 
TheXpert:
неверно. еще доступом к непубличным членам и методам класса.

Здесь терминологическое непонимание. "Область видимости" - не только то, кто видит метод. Но и что он сам видит.

 
fxsaber:

Здесь терминологическое непонимание.

все-таки область видимости и доступ это разные понятия и их лучше не смешивать
 
fxsaber:

Логичнее эту логику в конструктор запихать.

ну да, это более правильное решение! чтобы на один метод меньше было

тогда так:

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:
все-таки область видимости и доступ это разные понятия и их лучше не смешивать
вот поэтомуи возник у меня вопрос, куда бы воткнуть способ обнаружения, что прошлый запуск был аварийно завершен, сейчас структура кода компактная у меня, все четко по шаблону что выше показывал
Причина обращения: