mql5 언어의 특징, 미묘함 및 작업 방법 - 페이지 188

 
Nikolai Semko :
문제는 다른 클래스(이 경우 CTimer)의 개체가 이 클래스의 속성(변수)인 경우에도 포인터를 사용하여 비정적 클래스 메서드 를 실행하는 방법입니다.

당신은 할 수 없습니다 .... 당신은 물론, 다른 객체에 대한 포인터를 전달하고 거기에 있는 포인터의 이름을 변경하여 메서드를 호출할 수 있습니다. 하지만 메서드의 이름을 알아야 합니다. IMHO 혼란스러운 시스템 밖으로

추신: 하지만 어제 작성했습니다. @fxsaber 예제를 사용하고 상속합니다. 각 클래스는 OnTimer를 호출하고 루프의 기본 클래스에만 남아 어떤 타이머에 어떤 타이머 간격이 있는지 확인하고 정적 메서드에서 기본 타이머를 시작합니다.

 
Nikolai Semko :
문제는 다른 클래스(이 경우 CTimer)의 개체가 이 클래스의 속성(변수)인 경우에도 포인터를 사용하여 비정적 클래스 메서드 를 실행하는 방법입니다. 그리고 그것이 가능합니까? 나는 그렇지 않다.

- 템플릿

- 인터페이스

 

템플릿:

 template < typename C> class Timer
{
public :
  Timer(C* c)
  : p(c)
  {}

   void OnTimer ()
  {
    p-> OnTimer ();
  }
private :
  C* p;
}

class Handler
{
public :
  Handler()
  : t( this )
  {}

   void OnTimer () {}
private :
  Timer<Handler> t;
}

타이머 자체의 구현은 없으며 비 정적 함수를 호출하는 방법의 예(포럼에 직접 작성, 확인하지 않음)

 

거래, 자동 거래 시스템 및 거래 전략 테스트에 관한 포럼

MT5와 속도

fxsaber , 2020.10.04 11:56

프로그램이 제동 기계에서 실행 중인지 여부를 결정합니다.

 // Возвращает true, если тормозной VPS.
bool IsFreezeVPS()
{
   static bool FirstRun = true ;
   static bool Res;
  
   if (FirstRun)
  {
     if (Res = :: GetMicrosecondCount () - :: GetMicrosecondCount ())
      :: Alert ( "Warning: FreezeVPS - https://www.mql5.com/ru/forum/342090/page40#comment_18579094" );
    
    FirstRun = false ;
  }
  
   return (Res);
}
 
Nikolai Semko :
문제는 다른 클래스(이 경우 CTimer)의 개체가 이 클래스의 속성(변수)인 경우에도 포인터를 사용하여 비정적 클래스 메서드 를 실행하는 방법입니다. 그리고 그것이 가능합니까? 나는 그렇지 않다.

일반적으로 다음과 같습니다.

 #define USING_STD

#include <STD\Time\Timer.mqh>

class CTest{
   _tTimerEvent<CTest> cEvent;
public :
   CTest(_tTimer* mTimer):cEvent(& this ,mTimer){}
   void TimerEvent(_tTimerInfo &info){
       PrintFormat ( "Timer check in class at %llu, current delta %llu, count from last %u" ,info.lastTimer,info.delta,info.count);
   }
};

_tTimer gTimer1;
_tTimer gTimer2;

CTest gTest(&gTimer1);

int OnInit ( void )
  {
   EventSetMillisecondTimer ( 20 );
   ulong timer= GetMicrosecondCount ();
   if (!gTimer1) gTimer1.Reset(timer, 1000000 ); //1 s
   if (!gTimer2) gTimer2.Reset(timer, 2000000 ).Function(TimerEvent); //2 s
   TimerControl(timer);
   return ( INIT_SUCCEEDED );
  }

void OnDeinit ( const int reason){
   TimerControl( GetMicrosecondCount ());
// или gTimer.Free();
   EventKillTimer ();
  }

void OnTick ()
   {
   TimerControl( GetMicrosecondCount ());
  }
  
void OnTimer ( void )
  {
   TimerControl( GetMicrosecondCount ());
  }
//+------------------------------------------------------------------+
void TimerControl( ulong fTimer){
   gTimer1.Control(fTimer);
   gTimer2.Control(fTimer);
}

void TimerEvent(_tTimerInfo &info){
   PrintFormat ( "Timer check in function %llu, current delta %llu, count from last %u" ,info.lastTimer,info.delta,info.count);
}

https://github.com/sva04091979/STD/tree/TimerEvent에서 Liba를 다운로드하십시오. TimerEvent 분기가 아직 마스터에 병합되지 않았습니다.

 
Igor Makanu :

당신은 할 수 없습니다 .... 당신은 물론, 다른 객체에 대한 포인터를 전달하고 거기에 있는 포인터의 이름을 변경하여 메서드를 호출할 수 있습니다. 하지만 메서드의 이름을 알아야 합니다. IMHO 혼란스러운 시스템 밖으로

추신: 하지만 어제 작성했습니다. @fxsaber 예제를 사용하고 상속합니다. 각 클래스는 OnTimer를 호출하고 루프의 기본 클래스에만 남아 어떤 타이머에 어떤 타이머 간격이 있는지 확인하고 정적 메서드에서 기본 타이머를 시작합니다.

Igor, 나는 우리가 말하는 fxsaber 코드를 이해하지 못했습니다.

안드레이 트루하노비치 :

템플릿:

타이머 자체의 구현은 없으며 비 정적 함수를 호출하는 방법의 예만 있습니다(포럼에 직접 작성, 확인하지 않음)

고맙습니다. 시험을 마친. 아무것도 나오지 않습니다.

블라디미르 시마코프 :

일반적으로 다음과 같습니다.

https://github.com/sva04091979/STD/tree/TimerEvent에서 Liba를 다운로드하십시오. TimerEvent 분기가 아직 마스터에 병합되지 않았습니다.

고맙습니다. 그러나 포인터를 사용하여 비정적 클래스 메서드를 실행하는 방법도 찾지 못했습니다.


모두에게 감사하지만 내 한계로 인해 문제를 이해할 수 없게 공식화했거나 귀하의 솔루션을 보지 못했을 수 있습니다.
무엇이 필요합니까?
다음은 지표의 예입니다.
CTestTimer 클래스의 Timer4 메서드( 파란색으로 강조 표시됨) 는 현재 CTimer::NewTimer 클래스에 전달되는 CTimer 클래스( CTimer:: OnTimer 메서드 루프에서)의 포인터를 사용하여 시작해야 합니다. 생성자는 CTestTimer 클래스의 개체가 생성될 때 실행됩니다.
나는 이미 모든 것을 시도했습니다. 막다른 골목에. 실제로 이 메서드에 대한 포인터를 받는 것은 불가능합니다. C++에서는 다음을 통해 작동합니다. typedef void (CTestTimer::*TFun)();
그리고 이상한 오류: 'Timer4' - 이 함수 유형에 대한 포인터는 아직 지원되지 않습니다.
"안녕" - MQ가 이 문제를 더 나은 시간으로 연기한 것처럼.

 #property indicator_chart_window
#include <Timer.mqh> // https://www.mql5.com/ru/code/31306

//+------------------------------------------------------------------+
class CTestTimer {
 private :
   // typedef void (CTestTimer::*TFunc2)(); // так работает в C++, но здесь не работает
 public :
   int x4;
   CTestTimer() {
      x4= 0 ;
       // TFunc2 p=CTestTimer::Timer4;
       // TFunc2 p=Timer4;
       // timers.NewTimer(700,p);
       timers.NewTimer( 700 , CTestTimer::Timer4 ); // ошибка 'Timer4' - pointer to this function type is not supported yet
   };
   ~CTestTimer(){};
   void Timer4() {
      x4++;
       if (x4== 7 ) timers.KillTimer ( CTestTimer::Timer4 ); // удаляем этот таймер
   }
};
//+------------------------------------------------------------------+


int x1= 0 ;
int x2= 0 ;
int x3= 0 ;
CTestTimer X= new CTestTimer;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnInit () {
   timers.NewTimer( 500 ,  Timer1) ; // создаем новый таймер с периодом обновления 500   милисекунд и функцией-обраточником Timer1()
   timers.NewTimer( 1000 , Timer2) ; // создаем новый таймер с периодом обновления 1000  милисекунд и функцией-обраточником Timer2()
   timers.NewTimer( 2000 , Timer3) ; // создаем новый таймер с периодом обновления 2000  милисекунд и функцией-обраточником Timer3()
   timers.NewTimer( 100 ,  Timer5) ; // создаем новый таймер с периодом обновления 100   милисекунд и функцией-обраточником Timer5()
   return ( INIT_SUCCEEDED );
}
//+------------------------------------------------------------------+
void OnDeinit ( const int reason) {
   Comment ( "" );
}
//+------------------------------------------------------------------+
int OnCalculate ( const int rates_total, const int prev_calculated, const int begin, const double &price[]) {
   return (rates_total);
}
//+------------------------------------------------------------------+
void Timer1() {   // данная функция вызывается каждые 500 миллисекунд
   x1++;
   if (x1== 50 ) timers.KillTimer(Timer1); // удаляем этот таймер
}
//+------------------------------------------------------------------+
void Timer2() {   // данная функция вызывается каждые 1000 миллисекунд
   x2++;
   if (x2== 22 ) timers.KillTimer(Timer2); // удаляем этот таймер
}
//+------------------------------------------------------------------+
void Timer3() {   // данная функция вызывается каждые 2000 миллисекунд
   x3++;
   if (x3== 10 ) timers.KillTimer(Timer3); // удаляем этот таймер
}
//+------------------------------------------------------------------+
void Timer5() {   // данная функция вызывается каждые 100 миллисекунд
   if (x1== 50 ) timers.KillTimer(Timer5); // удаляем этот таймер
   Comment ( "x1=" + string (x1)+ ";\nx2=" + string (x2)+ ";\nx3=" + string (x3)+ ";\nx3=" + string ( X.x4 )+ "\nВсего таймеров - " + string (timers.GetN()));
}
//+------------------------------------------------------------------+
이 문제는 MQL5 언어의 현재 상태에서 해결책이 없는 것 같습니다.
 
Nikolai Semko :

Igor, 나는 우리가 말하는 fxsaber 코드를 이해하지 못했습니다.

https://www.mql5.com/en/forum/325418/page4#comment_16116740

이 코드의 값 .... 글쎄, 당신은 코드의 어느 곳에서나 자신의 동적 개체를 만들 수 있습니다 .... 업데이트에 대해 걱정할 필요가 없습니다. 프로그램을 종료하면 못을 박을 것입니다.

그런 타이머의 수는 상상에 의해서만 제한됩니다 ... 스프라이트를 움직이고 싶었습니다-화면의 왼쪽 가장자리에서 오른쪽으로 기어가는 개체를 만들었습니다. 그리고 스스로 죽었습니다-말하자면 완전한 자율성

... 예제를 작성하기에는 너무 게으르고 흥미로운 작업이 아닙니다.

 
Igor Makanu :

https://www.mql5.com/en/forum/325418/page4#comment_16116740

이 코드의 값 .... 글쎄, 당신은 코드의 어느 곳에서나 자신의 동적 개체를 만들 수 있습니다 .... 업데이트에 대해 걱정할 필요가 없습니다. 프로그램을 종료하면 못을 박을 것입니다.

그런 타이머의 수는 상상에 의해서만 제한됩니다 ... 스프라이트를 움직이고 싶었습니다-화면의 왼쪽 가장자리에서 오른쪽으로 기어가는 개체를 만들었습니다. 그리고 스스로 죽었습니다-말하자면 완전한 자율성

... 예제를 작성하기에는 너무 게으르고 흥미로운 작업이 아닙니다.

네, 빠르게 살펴보았습니다.
이 순간을 이해하지 못했다

 virtual void 0 ;
virtual void 0 ;
 
Nikolai Semko :

네, 빠르게 살펴보았습니다.
이 순간을 이해하지 못했다

지금 코드가 왜 이렇게 생겼는지 모르겠지만 다음과 같았어야 했습니다.

 virtual void OnInit () = 0 ;
 virtual void OnTick () = 0 ;
 virtual void OnDeinit ( const int )= 0 ;

그러나 타이머의 경우 이러한 방법이 필요하지 않습니다. IMHO

추신: 개체는 다음과 같이 스스로를 죽일 수 있습니다.

 delete & this ;
 
Igor Makanu :

지금 코드가 왜 이렇게 생겼는지 모르겠지만 다음과 같았어야 했습니다.

그러나 타이머의 경우 이러한 방법이 필요하지 않습니다. IMHO

추신: 개체는 다음과 같이 스스로를 죽일 수 있습니다.

당신과 @fxsaber 덕분에 알았습니다. 내 저금통에 저장했습니다.

그러나 물론이 코드에는 내 질문에 대한 답변이 없습니다.