Mql5 dilinin özellikleri, incelikleri ve çalışma yöntemleri - sayfa 188

 
Nikolai Semko :
Soru, başka bir sınıfın nesnesi (bu durumda, CTimer) bu sınıfın bir özelliği (değişkeni) olsa bile, bir işaretçi kullanarak statik olmayan bir sınıf yönteminin nasıl çalıştırılacağıdır.

yapamazsınız .... elbette, başka bir nesneye bir işaretçi iletebilir ve oradaki işaretçiyi yöntemi çağırmak için yeniden adlandırabilirsiniz .... ancak yöntemin adını bilmeniz gerekir, IMHO kafa karıştırıcı bir sistem dönecek dışarı

Not: ama dün yazdım, @fxsaber örneğini kullanın ve devralın, her sınıf OnTimer öğesini çağırır, hangi zamanlayıcının hangi zamanlayıcı aralığına sahip olduğunu kontrol etmek için döngüde yalnızca temel sınıfta kalır ve statik yöntemde ana zamanlayıcıyı başlatır

 
Nikolai Semko :
Soru, başka bir sınıfın nesnesi (bu durumda, CTimer) bu sınıfın bir özelliği (değişkeni) olsa bile, bir işaretçi kullanarak statik olmayan bir sınıf yönteminin nasıl çalıştırılacağıdır. Ve mümkün mü? Korkarım öyle değil.

- şablonlar

- arayüzler

 

şablonlar:

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

zamanlayıcının kendisinin uygulaması yoktur, yalnızca statik olmayan bir işlevin nasıl çağrılacağına dair bir örnek (doğrudan foruma yazıldı, kontrol edilmedi)

 

Ticaret, otomatik ticaret sistemleri ve ticaret stratejilerinin test edilmesi hakkında forum

MT5 ve iş başında hız

fxsaber , 2020.10.04 11:56

Fren makinesinde bir programın çalışıp çalışmadığını belirler.

 // Возвращает 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 :
Soru, başka bir sınıfın nesnesi (bu durumda, CTimer) bu sınıfın bir özelliği (değişkeni) olsa bile, bir işaretçi kullanarak statik olmayan bir sınıf yönteminin nasıl çalıştırılacağıdır. Ve mümkün mü? Korkarım öyle değil.

Genel olarak, şöyle görünür:

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

Liba'yı buradan indirin: https://github.com/sva04091979/STD/tree/TimerEvent. TimerEvent şubesi henüz master ile birleştirilmedi.

 
Igor Makanu :

yapamazsınız .... elbette, başka bir nesneye bir işaretçi iletebilir ve oradaki işaretçiyi yöntemi çağırmak için yeniden adlandırabilirsiniz .... ancak yöntemin adını bilmeniz gerekir, IMHO kafa karıştırıcı bir sistem dönecek dışarı

Not: ama dün yazdım, @fxsaber örneğini kullanın ve devralın, her sınıf OnTimer öğesini çağırır, hangi zamanlayıcının hangi zamanlayıcı aralığına sahip olduğunu kontrol etmek için döngüde yalnızca temel sınıfta kalır ve statik yöntemde ana zamanlayıcıyı başlatır

Igor, hangi fxsaber kodundan bahsettiğimizi anlamadım

Andrey Trukhanoviç :

şablonlar:

zamanlayıcının kendi uygulaması yoktur, yalnızca statik olmayan bir işlevin nasıl çağrılacağına dair bir örnek (doğrudan foruma yazıldı, kontrol edilmedi)

Teşekkür ederim. Sınanmış. Hiçbir şey çıkmıyor.

Vladimir Simakov :

Genel olarak, şöyle görünür:

Liba'yı buradan indirin: https://github.com/sva04091979/STD/tree/TimerEvent. TimerEvent şubesi henüz master ile birleştirilmedi.

Teşekkür ederim. Ancak, bir işaretçi kullanarak statik olmayan bir sınıf yöntemini nasıl çalıştıracağımı da bulamadım.


Herkese teşekkürler ama sorunu anlaşılmaz bir şekilde formüle etmiş olabilirim ya da kısıtlılıklarımdan dolayı çözümünüzü görememiş olabilirim.
İhtiyaç duyulan şey?
İşte bir gösterge örneği.
CTestTimer sınıfının Timer4 yönteminin ( mavi renkle vurgulanmıştır), şu anda CTimer::NewTimer sınıfına iletilen CTimer sınıfından ( CTimer:: OnTimer yöntem döngüsünde) bir işaretçi kullanılarak başlatılması gerekir. yapıcı, CTestTimer sınıfının bir nesnesi oluşturulduğunda yürütülür.
Ben zaten her şeyi denedim. Bir çıkmazda. Bu yöntemde işaretçiyi almak gerçekten imkansız. C++'da bu şu şekilde çalışır: typedef void (CTestTimer::*TFun)();
Ve bazı garip hata: 'Timer4' - bu işlev türünün işaretçisi henüz desteklenmiyor
"Güle güle" - sanki MQ bu konuyu daha iyi zamanlara erteledi.

 #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 dilinin mevcut durumunda bu sorunun çözümü yok gibi görünüyor
 
Nikolai Semko :

Igor, hangi fxsaber kodundan bahsettiğimizi anlamadım

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

bu kodun değeri .... peki, kodun herhangi bir yerinde kendi dinamik nesnenizi oluşturabilirsiniz .... ve onu güncelleme konusunda endişelenmeyin ve programdan çıktığınızda çivilenmiş olacaktır.

bu tür zamanlayıcıların sayısı sadece hayal gücü ile sınırlıdır ... Sprite'ı hareket ettirmek istedim - ekranın sol kenarından sağa doğru sürünen ve kendini öldüren bir nesne yarattım - tabiri caizse, tam özerklik

... bir örnek yazmak için çok tembel, ilginç bir görev değil

 
Igor Makanu :

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

bu kodun değeri .... peki, kodun herhangi bir yerinde kendi dinamik nesnenizi oluşturabilirsiniz .... ve onu güncelleme konusunda endişelenmeyin ve programdan çıktığınızda çivilenmiş olacaktır.

bu tür zamanlayıcıların sayısı sadece hayal gücü ile sınırlıdır ... Sprite'ı hareket ettirmek istedim - ekranın sol kenarından sağa sürünen ve kendini öldüren bir nesne yarattım - tabiri caizse, tam özerklik

... bir örnek yazmak için çok tembel, ilginç bir görev değil

evet hızlıca baktım.
bu anı anlamadım

 virtual void 0 ;
virtual void 0 ;
 
Nikolai Semko :

evet hızlıca baktım.
bu anı anlamadım

Kodun neden şimdi böyle göründüğünü bilmiyorum, ama şöyle olmalıydı:

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

ancak zamanlayıcı için bu yöntemler gerekli değildir, IMHO

Not: bir nesne kendini bu şekilde öldürebilir

 delete & this ;
 
Igor Makanu :

Kodun neden şimdi böyle göründüğünü bilmiyorum, ama şöyle olmalıydı:

ancak zamanlayıcı için bu yöntemler gerekli değildir, IMHO

Not: bir nesne kendini bu şekilde öldürebilir

anladım, teşekkürler ve @fxsaber . Onu kumbarama kaydettim.

Ama tabii ki bu kodda sorumun cevabı yok.