MQL5中的OOP问题 - 页 39

 

现在并不奇怪,为什么这里没有足够的沃尔昌斯基,硬汉内幕预告或他使用的任何东西))


我3个月前从网站外下载了win10home,甚至没有时间配置基本设置,启动时选项图标打不开,是***********。

 
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.我生成了大量的setters和getters,但无法摆脱静态变量的束缚


我试图再次重写代码。

//+------------------------------------------------------------------+
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:
目标是什么,你想得到什么?

一切都是有效的,但目标是获得知识))))。

我是如何做到的。

- 有一个基类,所有的计算都在这个基类中进行,它存储了TC设置,我们从它那里继承了子类,这些子类通过它们的TC工作。

- 我认为通过将打开的文件 的句柄传递给所有的子代,将文件保存到一个文件中是合理的;在这种情况下,save()方法再次出现在基类中

- 应该在事件/标志发生时进行保存--你不知道是哪个子孙发起的,什么时候发起的,但把几十个结构保存到一个新文件中比弄清楚它更快。

- 为什么不做一个类和一个数组的设置?- 我必须将一两个方法声明为虚拟,并将它们添加到每个TS中。

- 问题是:我正试图摆脱静态变量,希望有一个我不知道的绝地的OOP技巧。





SZY: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:

也可能是我什么都不明白。

我觉得我什么都没看懂,上个月我斜着看了这篇文章,这个月又回来看了,但需要检验一下可行性

Hubr:Singleton or static class?

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

- 问题:我想摆脱静态变量的束缚,希望有一个我不知道的绝地求生的OOP技巧

为什么这是个问题?如果你需要,你不需要脱离静态变量

我还是不明白写需要标志取决于什么。

在我的例子中,如果有变化,它就会被设置。

你希望它如何设置?

 
Koldun Zloy:

为什么这是个问题?如果你需要一个静态变量,你不需要走开。

那么问题就解决了!- 这就是最初的做法。

ZS:已经开始试验静态结构...我只看到了初始化的问题,然后是代码的可读性,我尝试了变体flag.saveRequired,然后是flagsave.Required,然后我进入了重载运算符=,反正,这些都是废话。 如果你通过私有静态变量,并为其添加setter和getter,最终会使代码更容易和可读,但正如他们所说:我们不是在寻找简单的方法....。祝晦涩难懂的视频的作者一切顺利...

 
Fast235:

现在并不奇怪,为什么这里没有足够的沃尔昌斯基,硬汉内幕预告或他使用的任何东西))

我3个月前从网站外下载了win10home,甚至没有时间配置基本设置,启动时选项图标打不开,是***********。

只是很忙,论坛也很耗时间,我不建议安装Insider预览版,现在Vinda每周都会安装新的版本 最好从MS网站下载稳定版。这是我幼稚的好奇仍然在一个地方玩耍:)