MQL5의 OOP에 대한 질문 - 페이지 22

 
Vladimir Simakov :

1. new 연산자 는 포인터를 반환합니다. 물론 개발자가 암시적 역참조로 마음을 정했으므로 버전이 작동하지만 문서화되지 않은 작업에는 관여하지 않는 것이 좋습니다.

2. 물론 우리는 C ++를 가지고 있지 않지만 매우 유사하므로 초기화 목록(효율성에 대해서는 잘 모르겠습니다)이 정결합니다.

귀하의 옵션이 작동하는지 확인했으며 논리적으로 더 정확합니다.

 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) 전략_1::전략_1

2019.08.31 22:07:35.196 tst (EURUSD,H1) 컨텍스트::컨텍스트

2019.08.31 22:07:35.196 tst (EURUSD,H1) 전략_2::전략_2

2019.08.31 22:07:35.196 tst (EURUSD,H1) 컨텍스트::컨텍스트

2019.08.31 22:07:35.196 tst (EURUSD,H1) Strategy_1::알고리즘

2019.08.31 22:07:35.196 tst (EURUSD,H1) Strategy_2::알고리즘

2019.08.31 22:07:35.197 tst (EURUSD,H1) Strategy_1::알고리즘

초기화 중에 생성된 포인터와 개체 자체가 손실되지 않았으며 인터페이스의 메서드가 클래스 1 및 2의 메서드를 대체하지 않았습니다. 모든 것이 의도한 대로 작동하는 것 같습니다.

 

초기화하는 동안 코드 섹션이 반복되는 것을 피하는 방법은 무엇입니까? - 생성자에서는 불가능

 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 :

초기화하는 동안 코드 섹션이 반복되는 것을 피하는 방법은 무엇입니까? - 생성자에서는 불가능

인터페이스 대신 일반 클래스를 만듭니다. 거기에 *m을 넣고 메서드로 만듭니다. bool SomeMethod {if ( CheckPointer (m)) return false; m=신규...; true를 반환합니다.}
알고리즘에서 if (SomeMethod()) ...
 
Vladimir Simakov :
인터페이스 대신 일반 클래스를 만듭니다. 거기에 *m을 넣고 bool SomeMethod {if (CheckPointer(m)) return false; m=신규...; true를 반환합니다.}
알고리즘에서 if (SomeMethod()) ...

아니요, 인터페이스가 필요합니다. 모든 틱 에서 모든 것을 가져올 필요가 없다는 것이 매우 멋진 것으로 판명되었습니다. - 틱당 하나의 전략에 대해 한 번만 호출할 것입니다. 일반적으로 이 모든 구성이 마음에 들지만 이것이 내 문제가 해결되어야 하는 방법이었습니다.

 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();
  }
//+------------------------------------------------------------------+
 

예제를 약간 수정했습니다. 모든 것이 작동하지만 제 생각에는 다음과 같아야 합니다.

 //+------------------------------------------------------------------+
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

하지만 어떤 이유로 CStrategy::Algorithm(void) 메서드의 본문을 제거하면 오류가 발생합니다. 'Algorithm' - 함수 에는 본문이 있어야 합니다.

왜 오류? - 결국 가상 한정자를 사용하여 CStrategy::Algorithm(void) 메서드를 선언합니다.

 
Igor Makanu :

예제를 약간 수정했습니다. 모든 것이 작동하지만 제 생각에는 다음과 같아야 합니다.

하지만 어떤 이유로 CStrategy::Algorithm(void) 메서드의 본문을 제거하면 오류가 발생합니다. 'Algorithm' - 함수 에는 본문이 있어야 합니다.

왜 오류? - 결국 가상 한정자를 사용하여 CStrategy::Algorithm(void) 메서드를 선언합니다.

추상 메서드는 자손에서 구현되어야 합니다. 다시 한 번 말씀드리지만 여기에는 인터페이스가 필요하지 않습니다.
 
가상 무효 알고리즘()=0;
그래서 시도
 
Vladimir Simakov :
가상 무효 알고리즘()=0;
그래서 시도
아니요, 그것도 작동하지 않습니다. 추상화가 선언된 경우 구현하십시오.
 
Vladimir Simakov :
아니요, 그것도 작동하지 않습니다. 추상화가 선언된 경우 구현하십시오.

내 생각에 컴파일러는 단순히 인터페이스의 Algorithm() 메서드와 선언된 가상 void Algorithm()을 virtual modifier로 인해 다른 메서드로 인식합니다.

블라디미르 시마코프 :
추상 메서드는 자손에서 구현되어야 합니다. 다시 한 번 말씀드리지만 여기에는 인터페이스가 필요하지 않습니다.

인터페이스가 필요하므로 어드바이저의 설정에 따라 6가지 전략에 대해 서로 다른 행동을 선언하는 것이 나에게 편리합니다.

이제 다음과 같이:

 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 ; } } }

그래서 Algorithm() 메서드의 본체를 최소화하고 싶습니다. 기본 클래스를 올바르게 작성하면 CStrategy 클래스 위의 예제에서 Algorithm() 자체에 5-10줄 이하가 됩니다.


인터페이스 없이 이 코드를 작성하는 방법은 무엇입니까? - 이제 모든 것이 간단하고 남은 모든 것은 전략 알고리즘 자체를 매 틱 또는 덜 자주 끌어오는 것입니다.

 

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

오늘 밤에 보여드리겠습니다. 이제 전화에서.