MQL5'te OOP hakkında sorular - sayfa 22

 
Vladimir Simakov :

1. Yeni operatör bir işaretçi döndürür, elbette geliştiriciler örtük referans kaldırma ile kararlarını verdiler, bu nedenle sürümünüz çalışır, ancak belgelenmemiş şeylere karışmamak daha iyidir.

2. Tabii ki, elimizde C++ yok, ancak çok benzer, bu nedenle başlatma listeleri (verimliliği bilmiyorum) koşer.

Seçeneğin işe yarayıp yaramadığını kontrol ettim ve mantıksal olarak daha doğru:

 interface IStrategy
  {
   void Algorithm()  { Print ( "Это не должно вызываться!!!" ); }
  };
//+------------------------------------------------------------------+
class Strategy_1 : public IStrategy
  {
public :
                     Strategy_1()   { Print ( __FUNCTION__ ); }
   void               Algorithm()    { Print ( __FUNCTION__ ); }
  };
//+------------------------------------------------------------------+
class Strategy_2 : public IStrategy
  {
public :
                     Strategy_2()   { Print ( __FUNCTION__ ); }
   void               Algorithm()    { Print ( __FUNCTION__ ); }
  };
//+------------------------------------------------------------------+
class Context
  {
public :
   IStrategy         *s;
                     Context(IStrategy *_strategy) { Print ( __FUNCTION__ ); s = _strategy;              }
                    ~Context()                     { delete s;                                        }
   void               GetStrategy()                 { s.Algorithm();                                   }
  };
//+------------------------------------------------------------------+
Context c1( new Strategy_1);
Context c2( new Strategy_2);
//+------------------------------------------------------------------+
void OnStart ()
  {
   c1.GetStrategy();
   c2.GetStrategy();
   
   c1.s.Algorithm();
  }
//+------------------------------------------------------------------+

2019.08.31 22:07:35.196 tst (EURUSD,H1) Strateji_1::Strateji_1

2019.08.31 22:07:35.196 tst (EURUSD,H1) Bağlam::Bağlam

2019.08.31 22:07:35.196 tst (EURUSD,H1) strateji_2::strateji_2

2019.08.31 22:07:35.196 tst (EURUSD,H1) Bağlam::Bağlam

2019.08.31 22:07:35.196 tst (EURUSD,H1) Strateji_1::Algoritma

2019.08.31 22:07:35.196 tst (EURUSD,H1) Strateji_2::Algoritma

2019.08.31 22:07:35.197 tst (EURUSD,H1) Strateji_1::Algoritma

başlatma sırasında oluşturulan işaretçi ve nesnenin kendisi kaybolmadı ve arabirimdeki yöntem, sınıf 1 ve 2'deki yöntemlerin yerini almadı - her şey amaçlandığı gibi çalışıyor gibi görünüyor

 

başlatma sırasında kod bölümlerini tekrar etmekten nasıl kaçınılır? - yapıcıda mümkün değil

 class MyClass
{
   public :
      MyClass()         { Print ( "Create MyClass" );}
};

interface IStrategy
  {
   void Algorithm()  { Print ( "Это не должно вызываться!!!" ); }
  };
//+------------------------------------------------------------------+
class Strategy_1 : public IStrategy
  {
   private :
  MyClass   *m;
public :
                     Strategy_1()   { Print ( __FUNCTION__ ); }
   void               Algorithm()    { if (m== NULL ) m = new MyClass; else { } } 
  };
//+------------------------------------------------------------------+
class Strategy_2 : public IStrategy
  {
   private :
  MyClass   *m;
public :
                     Strategy_2()   { Print ( __FUNCTION__ ); }
   void               Algorithm()    { if (m== NULL ) m = new MyClass; else { } }
  };
//+------------------------------------------------------------------+
class Context
  {
private :
   IStrategy         *s;
public :
                     Context(IStrategy *_strategy) { Print ( __FUNCTION__ ); s = _strategy;              }
                    ~Context()                     { delete s;                                        }
   void               GetStrategy()                 { s.Algorithm();                                   }
  };
//+------------------------------------------------------------------+
Context c1( new Strategy_1);
Context c2( new Strategy_2);
//+------------------------------------------------------------------+
void OnStart ()
  {
   c1.GetStrategy();
   c2.GetStrategy();
  }
//+------------------------------------------------------------------+
 
Igor Makanu :

başlatma sırasında kod bölümlerini tekrar etmekten nasıl kaçınılır? - yapıcıda mümkün değil

Arayüz yerine normal bir sınıf yaparsınız. Oraya *m koyarsınız ve onu bir metod yaparsınız bool SomeMethod {if ( CheckPointer (m)) return false; m=yeni...; doğru döndür;}
Algoritmada if (SomeMethod()) ...
 
Vladimir Simakov :
Arayüz yerine normal bir sınıf yaparsınız. Oraya *m koyarsınız ve onu bir metod yaparsınız bool SomeMethod {if (CheckPointer(m)) return false; m=yeni...; doğru dön;}
Algoritmada if (SomeMethod()) ...

hayır, arayüz gerekli - her tikte her şeyi çekmenin gerekli olmayacağı çok güzel - her tik için bir stratejiye bir çağrı yapacağım - genel olarak, tüm bunların konfigürasyonunu beğensem de, öyle görünüyor sorunumun bu şekilde çözülmesi gerektiğini:

 class MyClass
{
   public :
      MyClass()         { Print ( "Create MyClass" );}
};

interface IStrategy
  {
   void Algorithm()  { Print ( "Это не должно вызываться!!!" ); }
  };
  
class CStrategy : public IStrategy
{
protected :
   MyClass  *m;
   void Init()   {  m= new MyClass; }
};
//+------------------------------------------------------------------+
class Strategy_1 : public CStrategy
  {
public :
                     Strategy_1()   { Print ( __FUNCTION__ ); }
   void               Algorithm()    { if (m== NULL ) Init(); else { } } 
  };
//+------------------------------------------------------------------+
class Strategy_2 : public CStrategy
  {
public :
                     Strategy_2()   { Print ( __FUNCTION__ ); }
   void               Algorithm()    { if (m== NULL ) Init(); else { } }
  };
//+------------------------------------------------------------------+
class Context
  {
private :
   IStrategy         *s;
public :
                     Context(IStrategy *_strategy) { Print ( __FUNCTION__ ); s = _strategy;              }
                    ~Context()                     { delete s;                                        }
   void               GetStrategy()                 { s.Algorithm();                                   }
  };
//+------------------------------------------------------------------+
Context c1( new Strategy_1);
Context c2( new Strategy_2);
//+------------------------------------------------------------------+
void OnStart ()
  {
   c1.GetStrategy();
   c2.GetStrategy();
  }
//+------------------------------------------------------------------+
 

Örneğimi biraz değiştirdim - her şey çalışıyor, ama bence şöyle görünmeli:

 //+------------------------------------------------------------------+
interface IStrategy
{   void Algorithm()                 { Print ( "Это не должно запускаться!!!" ); } };
//+------------------------------------------------------------------+
class CStrategy : public IStrategy
{
protected :
   int x;
public :
   virtual void Algorithm()         { Print ( "Это не должно запускаться!!!" ); } };
//+------------------------------------------------------------------+
class CStrategy_01: public CStrategy
{
public :
   CStrategy_01()                   { Print ( __FUNCTION__ );  x = 01 ;         }
   void Algorithm()                 { Print ( __FUNCTION__ , ", x = " ,x);       } };
//+------------------------------------------------------------------+
class CStrategy_02: public CStrategy
{
public :
   CStrategy_02()                   { Print ( __FUNCTION__ );   x = 02 ;        }
   void Algorithm()                 { Print ( __FUNCTION__ , ", x = " ,x);       } };
//+------------------------------------------------------------------+
class Context
{
private :
   IStrategy         *s;
public :
   Context(IStrategy *_strategy)    { Print ( __FUNCTION__ ); s = _strategy;  }
   ~Context()                       { delete s;                            }
   void               GetStrategy()  { s.Algorithm();                       } };
//+------------------------------------------------------------------+
Context c1( new CStrategy_01);
Context c2( new CStrategy_02);
//+------------------------------------------------------------------+
void OnStart ()
{  c1.GetStrategy();
   c2.GetStrategy(); }
//+------------------------------------------------------------------+



0 15:57:17.100 tst EURUSD,H1: CStrategy_01::CStrategy_01 0 15:57:17.100 tst EURUSD,H1: Context::Context 0 15:57:17.100 tst EURUSD,H1: CStrategy_02::CStrategy_02 0 15:57:17.100 tst EURUSD,H1: Context::Context 0 15:57:17.100 tst EURUSD,H1: initialized 0 15:57:17.100 tst EURUSD,H1: CStrategy_01::Algorithm, x = 1 0 15:57:17.100 tst EURUSD,H1: CStrategy_02::Algorithm, x = 2

ancak herhangi bir nedenle, CStrategy::Algorithm(void) yönteminin gövdesini kaldırırsam bir hata olacaktır: 'Algorithm' - işlevin bir gövdesi olmalıdır

neden hata? - sonuçta, sanal değiştiriciyle CStrategy::Algorithm(void) yöntemini ilan ediyorum

 
Igor Makanu :

Örneğimi biraz değiştirdim - her şey çalışıyor, ama bence şöyle görünmeli:

ancak herhangi bir nedenle, CStrategy::Algorithm(void) yönteminin gövdesini kaldırırsam bir hata olacaktır: 'Algorithm' - işlevin bir gövdesi olmalıdır

neden hata? - sonuçta, sanal değiştiriciyle CStrategy::Algorithm(void) yöntemini ilan ediyorum

Torunlarda soyut bir yöntem uygulanmalıdır. Bir kez daha söylüyorum, burada arayüze gerek yok.
 
sanal boşluk Algoritması()=0;
O zaman dene
 
Vladimir Simakov :
sanal boşluk Algoritması()=0;
O zaman dene
Hayır, o da çalışmayacak. Soyutlama beyan edilmişse, lütfen uygulayın.
 
Vladimir Simakov :
Hayır, o da çalışmayacak. Soyutlama beyan edilmişse, lütfen uygulayın.

Bence derleyici, arayüzden Algoritma () yöntemini ve sanal değiştirici nedeniyle bildirilen sanal geçersiz Algoritmasını () farklı yöntemler olarak algılıyor.

Vladimir Simakov :
Torunlarda soyut bir yöntem uygulanmalıdır. Bir kez daha söylüyorum, burada arayüze gerek yok.

arayüzlere ihtiyaç var, danışmanın ayarlarına bağlı olarak, 6 strateji için farklı davranışlar bildirmek benim için uygun (çok fazla strateji yok, ancak kaç tane sipariş sistemi araştırması var)

şimdi böyle:

 class CGrid {
private :
   int                StrategyCount;
   IStrategy         *Strategy[];
public :
   CGrid( int eamagicnumber, SSettingsForOrder &settingstrategy[]);
   ~CGrid(); };
//+------------------------------------------------------------------+
void CGrid::CGrid( int eamagicnumber, SSettingsForOrder &settingstrategy[]) {
   StrategyCount = ArraySize (settingstrategy);
   ArrayResize (Strategy, StrategyCount);
   for ( int i = 0 ; i < StrategyCount; i++) {
      settingstrategy[i].magicnumber = i+eamagicnumber;
       switch (settingstrategy[i].dealtype) {
       case NONE                  :  Strategy[i] = new CNONE(settingstrategy[i]);                   break ;
       case BUY                   :  Strategy[i] = new CBUY(settingstrategy[i]);                     break ;
       case ReOpenBUY             :  Strategy[i] = new CReOpenBUY(settingstrategy[i]);               break ;
       case ReversBUYToSellOnly   :  Strategy[i] = new CReversBUYToSellOnly(settingstrategy[i]);     break ;
       case ReversBUYAlwaysRevers :  Strategy[i] = new CReversBUYAlwaysRevers(settingstrategy[i]);   break ;
       case SELL                  :  Strategy[i] = new CSELL(settingstrategy[i]);                   break ;
       case ReOpenSELL            :  Strategy[i] = new CReOpenSELL(settingstrategy[i]);             break ;
       case ReversSELLToBuyOnly   :  Strategy[i] = new CReversSELLToBuyOnly(settingstrategy[i]);     break ;
       case ReversSELLAlwaysRevers:  Strategy[i] = new CReversSELLAlwaysRevers(settingstrategy[i]); break ; } } }

bu yüzden Algorithm() yöntemlerinin tüm gövdesini küçültmek istiyorum - eğer temel sınıfı doğru yazarsam - CSrategy sınıfının üstündeki örneğimde, o zaman Algorithm()'in kendisinde 5-10 satırdan fazla olmayacak


arayüz olmadan bu kod nasıl yazılır? - şimdi her şey kısa ve geriye kalan tek şey strateji algoritmalarını her tık veya daha az sıklıkta çekmek

 

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

Sana bu gece göstereceğim. Şimdi telefondan.