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

 

теперь не странно почему Волчанского тут стало мало, крепкий мужик Insider preview или как там использует))


месца 3 назад с офф сайта качнул win 10home, не успел даже настроить элементарные настройки , пуск-значок Параметры не открывается, да ***********

 
Koldun Zloy:

Вот пример:

попробовал под свою задачу полностью применить Ваш пример, но опять те же грабли - хочу в итоге флаг "требуется запись" получить при создании нового потомка из базового класса:

//+------------------------------------------------------------------+
class CStrategy
{
private:
   int f_save_required;
protected:
   int set;
   void              SaveRequiredFlags (const bool flag)                      { f_save_required++;  }
   int               SaveRequiredFlags (void) const                           { return(f_save_required); }
public:
                     CStrategy():f_save_required(0)                           {  Print(__FUNCSIG__,"save = ",f_save_required);  }
                     CStrategy(int setting):set(setting),f_save_required(0)   {  Print(__FUNCSIG__,"save = ",f_save_required);  }
                    ~CStrategy(){}

};
//+------------------------------------------------------------------+
class A: public CStrategy
{
public:
   void              SaveRequired (void)                                      { SaveRequiredFlags(true);                         }
   int               getSaveRequired (void) const                             { return(SaveRequiredFlags());                     }
                     A(int st_setting) : CStrategy(st_setting){}
                    ~A(){}
};
//+------------------------------------------------------------------+
class B: public CStrategy
{
public:
   void              SaveRequired(void)                                       { SaveRequiredFlags(true);                         }
   int               getSaveRequired (void) const                             { return(SaveRequiredFlags());                     }
                     B(int st_setting) : CStrategy(st_setting){}
                    ~B(){}
};
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   A *a = new A(1);
   B *b = new B(2);
   a.SaveRequired();
   a.SaveRequired();
   a.SaveRequired();
   a.SaveRequired();
   b.SaveRequired();
   Print(a.getSaveRequired());
   Print(b.getSaveRequired());
//---
   return(INIT_SUCCEEDED);
  }

2019.09.14 16:07:26.856 Builder_v1.00 (EURUSD,H1) CStrategy::CStrategy(int)save = 0

2019.09.14 16:07:26.856 Builder_v1.00 (EURUSD,H1) CStrategy::CStrategy(int)save = 0

2019.09.14 16:07:26.856 Builder_v1.00 (EURUSD,H1) 4

2019.09.14 16:07:26.856 Builder_v1.00 (EURUSD,H1) 1

пока все, что получилось:

1. не объявлять интерфейсы - вообще не было проблемой

2. порождаю множество сеттеров и геттеров, а уйти от статик переменной не получилось


попробовал и еще раз переписать код так:

//+------------------------------------------------------------------+
class CStrategy
{
private:
   int f_save_required;
protected:
   int set;
   void              SaveRequiredFlags (const bool flag)                      { f_save_required++;  }
   int               SaveRequiredFlags (void) const                           { return(f_save_required); }
public:
virtual  void        SaveRequired (void)                                      { SaveRequiredFlags(true);                         }
virtual  int         getSaveRequired (void) const                             { return(SaveRequiredFlags());                     }
                     CStrategy():f_save_required(0)                           {  Print(__FUNCSIG__,"save = ",f_save_required);  }
                     CStrategy(int setting):set(setting),f_save_required(0)   {  Print(__FUNCSIG__,"save = ",f_save_required);  }
                    ~CStrategy(){}

};
//+------------------------------------------------------------------+
class A: public CStrategy
{
public:
                     A(int st_setting) : CStrategy(st_setting){}
                    ~A(){}
};
//+------------------------------------------------------------------+
class B: public CStrategy
{
public:
                     B(int st_setting) : CStrategy(st_setting){}
                    ~B(){}
};
//+------------------------------------------------------------------+



//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   CStrategy *a = new A(1);
   CStrategy *b = new B(2);
   
   a.SaveRequired();
   a.SaveRequired();
   a.SaveRequired();
   a.SaveRequired();
   b.SaveRequired();
   Print(a.getSaveRequired());
   Print(b.getSaveRequired());
//---
   return(INIT_SUCCEEDED);
  }

результат один в один как в первом варианте, единственное это точно ушел от интерфейсов

 
А какая цель, что надо получить?
 
Dmitry Fedoseev:
А какая цель, что надо получить?

все работает, но цель получить знания ))))

как я сделал:

- есть базовый класс в котором все расчеты и он хранит настройки ТС, от него наследуем потомков которые работают по своим ТС

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

- запись целесообразно производить при возникновении события/ флаг - кто из потомков и когда это инициирует неизвестно, но быстрее записать десяток структур в новый файл, чем что то выяснять

- почему бы не сделать один класс и массив настроек? - требуется один или два метода объявлять как виртуальные и их и дописываю под каждую ТС

- проблема: старюсь уйти от статик переменной в надежде, что есть джедайский прием ООП который я не знаю





ЗЫ: модификаторы const хорошая штука, не жалею о потраченном времени - полезно, тут еще раз спасибо кто обсуждал!

 

Если в один файл, который открывается один раз, надо писать данные из всех объектов этого класса, то без статической переменной никак. И зачем от нее избавляться, если она больше всего подходит для решения этой задачи? Конечно можно и глобальную переменную объявить.

Вот если бы каждый объект открывал файл, писал и закрывал. Тогда достаточно было бы иметь имя файла в каждом объекте... Но и в этом случае лучше статическую переменную использовать, поскольку значение переменой везде и всегда одинаковое.

Или я ничего не понял)

 
Dmitry Fedoseev:

Если в один файл, который открывается один раз, надо писать данные из всех объектов этого класса, то без статической переменной никак. И зачем от нее избавляться, если она больше всего подходит для решения этой задачи? Конечно можно и глобальную переменную объявить.

Вот если бы каждый объект открывал файл, писал и закрывал. Тогда достаточно было бы иметь имя файла в каждом объекте... Но и в этом случае лучше статическую переменную использовать, поскольку значение переменой везде и всегда одинаковое.

Или я ничего не понял)

в файл который один раз открывается, в него записываем данные и сразу закрываем, чтобы не потерять данные если подвис терминал, запись от раз в минуты до раз в час - нет смысла держать столь долго открытый файл

давайте в коде, сейчас так:

// это один файл, его не трогаю, тут только конструктор и 3 метода из интерфейсов, чтобы дать стратегиям тик, чтобы закрыть их и вот чтобы записать все ТС в файл

//____________________________________________________________________
void EA::OnTick(double &profit[])
{
      for(int i = 0; i < StrategyCount; i++) profit[i] = Strategy[i].Strategy();  // запустили зоопарк стратегий и тут нам интересно дать им волю и узнать их профит, если ТС завершилась       
                                                                                  // она самостоятельно запустит "пустую стратегию", но профит будет возвращать первоначальный
      if(CStrategy::GetSaveRequired()) Save();                                    // вот тут узнаем состояние флага требуется ли запись состояния любой из ТС
}
//____________________________________________________________________
//это структура которая умеет открыть и записать файл, пример от fxsaber
struct FILE
{  const int handle;

  FILE( const string FileName, const int Flags ) : handle(::FileOpen(FileName, Flags)) {}
 ~FILE( void ) { if (this.handle != INVALID_HANDLE) ::FileClose(this.handle);  Print(__FUNCTION__);} 
};

//____________________________________________________________________
// метод для записи в файл состояния всех ТС, но проще записать все ТС один раз в файл, чем искать одну ТС..... в общем считаем, что скорость доступа к диску намного меньше чем работа с памятью
// используем структуру FILE - ну это просто удобно, объявили и забыли, она сама закроет файл когда уйдет из области видимости
void  EA::Save(void)
{  FILE f(DEF_PREFIX_FILE_NAME + IntegerToString(m_magic)+".bin",FILE_WRITE|FILE_BIN);
   for(int i = 0; i < StrategyCount; i++)
      Strategy[i].SaveSelfStatus(f.handle); 

}





// это основной файл (инклудник) в котором работаю, тут ТС 

//____________________________________________________________________
здесь опять все кратко и лаконично, но сделаю вывод в лог ошибки если возникнут при записи, сделаю именно здесь, т.к. только тут все модификации 
void CStrategy::SaveSelfStatus(const int handle)
{  FileWriteStruct(handle,m_setting);
   FileWriteStruct(handle,m_order_info);

}

 
Dmitry Fedoseev:

Или я ничего не понял

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

Хабр: Singleton (Одиночка) или статический класс?

Singleton (Одиночка) или статический класс?
Singleton (Одиночка) или статический класс?
  • habr.com
Статья будет полезна в первую очередь разработчикам, которые теряются на собеседованиях когда слышат вопрос «Назовите основные отличия синглтона от статического класса, и когда следует использовать один, а когда другой?». И безусловно будет полезна для тех разработчиков, которые при слове «паттерн» впадают в уныние или просят прекратить...
 
Igor Makanu:

- проблема: старюсь уйти от статик переменной в надежде, что есть джедайский прием ООП который я не знаю

Почему это проблема? Не надо уходить от статической переменной, если она Вам нужна.

Я так и не понял от чего зависит флаг необходимости записи.

В моём примере он устанавливается, если были изменения.

А как Вам надо?

 
Koldun Zloy:

Почему это проблема? Не надо уходить от статической переменной, если она Вам нужна.

тогда вопрос решен! - все так и сделал изначально

ЗЫ: начал уже эксперименты со статической структурой творить... вижу только проблемы с инициализацией, затем с читаемостью кода, пробовал варианты flag.saveRequired, затем flagsave.Required, затем уже понесло в перегрузить оператор =, в общем чепуха все это. Намного проще и читаемый код в итоге если сделать через приватную статик переменную и добавить к ней сеттер и геттер, но как говорится: мы не ищем легких путей.... всего наилучшего авторам непонятных видео...

 
Fast235:

теперь не странно почему Волчанского тут стало мало, крепкий мужик Insider preview или как там использует))

месца 3 назад с офф сайта качнул win 10home, не успел даже настроить элементарные настройки , пуск-значок Параметры не открывается, да ***********

Просто занят, а форум отнимает много времени.  Insider preview ставить не рекомендую, теперь Винда по разу в неделю устанавливает новый билд. Лучше с сайта MS скачать стабильный билд. Это у меня детское любопытство еще в одном месте играет :)