Hatalar, hatalar, sorular - sayfa 2657

 
Stanislav Korotky :

İşin aslı, sınıf ağacının ortak bir CWnd düğümüne sahip olmasıdır (CObject ayrıca, genellikle kökte).

CButton -> CWndObj -> CWnd -> CObject.

Yöntemdeki parametreyi CObject olarak değiştirirsek 2 kat daha fazla hata alırız:

Benzer bir sınıf hiyerarşisi, dizi olmayan durum için çalışır. İşte derlenmiş kod:

Soru, bir dizi için de nasıl çalıştırılacağıdır?

Şablonun yardımcı olduğunu biliyorum, ancak bundan kaçınmak istiyorum.

IMHO, miras hakkı ile şablonlar olmadan çalışmalıdır.

C++'da olduğu gibi kontrol edildi.

İşler. Ancak MQL bunu indeksli veya indekssiz sindirmez.

C++ için örneğiniz bu şekilde daha net olacaktır. Çalıştırın ve ne olduğunu görün)))

 class CWnd
{
public :
     int x;
    CWnd( int _x = 10 ) : x(_x) {}
};
class CButton : public CWnd
{
     int a;
public :
    CButton( int _a= 6 ) : CWnd(),a(_a) {}
};

class Collection
{
public :
    Collection(CWnd* ptr,size_t size) {
         for ( int i = 0 ; i < size; cout << ptr[i++].x<<endl);
    }
};

int main()
{
    CButton buttons[ 10 ];
    CWnd wnd[ 10 ];
    Collection data1(&wnd[ 0 ],_countof(wnd));
    cout << "------------------------------" << endl;
    Collection data2(&buttons[ 0 ],_countof(buttons));
     return 0 ;
}
 

Hmm canim. Ama sonra bir sonraki soru ortaya çıkıyor. İşte çalışan C++ kodu (zaten tam olarak olması gerektiği gibi ;-)).

 class Base
{
   public :
     virtual void method1( void ) { cout << "2\n" ; }
};

class Derived: public Base
{
   public :
     virtual void method1( void ) override { cout << "3\n" ; }
};

template < typename T>
class Wrapper
{
   public :
    Wrapper(T *ptr)
    {
      ptr->T::method1();
    }
};

int main()
{
  Derived d;
  d.Base::method1();   // ok
  Wrapper<Base> w(&d); // ok

   return 0 ;
}

Benzer bir MQL hata veriyor:

 class Base
{
   public :
     virtual void method1( void ) { Print ( __FUNCSIG__ ); }
};

class Derived: public Base
{
   public :
     virtual void method1( void ) override { Print ( __FUNCSIG__ ); }
};

template < typename T>
class Wrapper
{
   public :
    Wrapper(T *ptr)
    {
      ptr.T::method1(); // <<< 'Base' is not a class, struct or union
    }
};


void OnStart ()
{
  Derived d;
  d.Base::method1();   // ok
  Wrapper< Base > w(&d); // causes the error above
 
Stanislav Korotky :

Hmm canim. Ama sonra bir sonraki soru ortaya çıkıyor. İşte çalışan C++ kodu (zaten tam olarak olması gerektiği gibi ;-)).

Benzer bir MQL hata veriyor:

Sorunu bilmiyorum ama bence şöyle bir şey arıyorsunuz:

 typedef void (*PTR)( void );

MQL'de bir işlev işaretçisi void func(void)

bir sınıfta PTR türünde bir alan bildirebilir ve ardından ona bir işlev atayabilir ve ardından "işaretçiyi iptal edebilir" ve işlevi çağırabilirsiniz.

yordamsal bir tarzda yazılmış fonksiyonların sınıfa aktarılması ile sorunsuz çalışır, sınıf yöntemleri , büyük olasılıkla, bu kadar kolay aktarmanız mümkün olmayacak, dynamic_cast kullanmayı deneyebilirsiniz, ancak kod çok çıkacaktır. kafa karıştırıcı

 
Igor Makanu :

Sorunu bilmiyorum ama bence şöyle bir şey arıyorsunuz:

MQL'de bir işlev işaretçisi void func(void)

bir sınıfta PTR türünde bir alan bildirebilir ve ardından ona bir işlev atayabilir ve ardından "işaretçiyi iptal edebilir" ve işlevi çağırabilirsiniz.

yordamsal bir tarzda yazılmış fonksiyonların sınıfa aktarılması ile sorunsuz çalışır, sınıf yöntemleri , büyük olasılıkla, bu kadar kolay aktarmanız mümkün olmayacak, dynamic_cast kullanmayı deneyebilirsiniz, ancak kod çok çıkacaktır. kafa karıştırıcı

typedef, yöntemle çalışmaz.

dynamic_cast, varise (daha uzun zincir) doğru çalışır, yani, tabana yönelik işaretçi türetilmiş içeriyorsa, türetilmiş için yayınlayabilirsiniz ve NULL değilse (yani, atama normaldir), yöntemini çağırabilirsiniz. Ama durum tam tersi olduğunda, benim durumumda olduğu gibi, türetilecek bir işaretçi vardır, o zaman tanım gereği o da tabandır. Ve sanal yöntemine yapılan herhangi bir çağrı, işaretçinin türetilmiş "oturduğu" ve geçersiz kılınan uygulamayı çağırdığı anlamına gelir. Ve bir temele ihtiyacın var.

Bunun için C++'da yukarıdaki sözdizimsel yapı vardır, ancak MQL C++ değildir. Görünüşe göre henüz değil.

Kendim için bir geçici çözüm yaptım, ancak tüm görevlerde çalışamaz.

Tef ile yapılan tüm bu dansların anlamı, her zaman olduğu gibi, kafa karıştıran kodun "kütüphane" içinde kalması ve onu kullanan kodun kristal berraklığında ve basit hale gelmesidir.

 

test cihazında rand() nasıl başlatılır?

kod:

 input ulong param = 18446744073709551615 ;
void OnTick ()
   {
   }
//+------------------------------------------------------------------+
double OnTester ()
   {
       srand ( GetTickCount ()); 
       return ( rand ());
   }
//+------------------------------------------------------------------+

Bu sözde rastgele nesli pek sevmiyorum:


 
Igor Makanu :

test cihazında rand() nasıl başlatılır?

kod:

Bu sözde rastgele nesli pek sevmiyorum:


Yardım: MathRand

Not

İlk işlev çağrısından önce, sözde rasgele sayı üretecini başlangıç durumuna sıfırlamak için MathSrand işlevini kullanmanız gerekir.


MathSrand ile şimdi deneyin.

Документация по MQL5: Математические функции / MathRand
Документация по MQL5: Математические функции / MathRand
  • www.mql5.com
Математические функции / MathRand - справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
 
Vladimir Karputov :

Yardım: MathRand

Not

İlk işlev çağrısından önce, sözde rasgele sayı üretecini başlangıç durumuna sıfırlamak için MathSrand işlevini kullanmanız gerekir.

Teşekkürler, Kap!

bu test cihazıyla ilgili

bu kod da TESTER'da çalışmıyor

 input ulong param = 18446744073709551615 ;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit ()
   {
   MathSrand ( GetTickCount ()); 
   return ( INIT_SUCCEEDED );
   }
//+------------------------------------------------------------------+
void OnTick ()
   {
   }
//+------------------------------------------------------------------+
double OnTester ()
   {
       return ( rand ());
   }
//+------------------------------------------------------------------+
 
Igor Makanu :

Bence bir testçi ise MathSrand kullanmaya gerek yok.

Ancak bu yardımcı olmazsa, büyük olasılıkla bir aşamada test cihazı zorla MathSrand(GetTickCount()) öğesini çağırır.

Ardından MathSrand(int( GetMicrosecondCount()%1000000 )); deneyebilirsiniz.

Sonuçta ZY GetTickCount'un () her 15.625 milisaniyede bir değerleri değiştirdiğini unutmamak gerekir. Bu bir testçi için çok uzun bir süre.

 
Nikolai Semko :

Bence bir testçi ise MathSrand kullanmaya gerek yok.

bu, https://www.mql5.com/ru/docs/math/mathrand belgelerine aykırıdır

İlk işlev çağrısından önce, sözde rasgele sayı üretecini başlangıç durumuna sıfırlamak için MathSrand işlevini kullanmanız gerekir.

Alglib kaynakları arasında geçiş yapmak istemiyorum, ancak sinir ağı paketleri için NN ağırlıklarının rastgele bir değeriyle başlatma zorunludur, bunun MQL yardım materyaline göre yapıldığından şüpheleniyorum - yani. kullanılmış srand()

onlar. MQL programlarının test cihazı içinde böyle bir NS paketi ile kullanılması büyük olasılıkla bir işlemci çekirdeğinde gerçekleşecektir - ilk NS ağırlıkları aynı değerlere sahip olacak mı?

srand() olmadan daha da havalı

 int OnInit ()
   {
   return ( INIT_SUCCEEDED );
   }
//+------------------------------------------------------------------+
void OnTick ()
   {
   }
//+------------------------------------------------------------------+
double OnTester ()
   {
       return ( rand ());
   }
//+------------------------------------------------------------------+
 
Igor Makanu :

bu, https://www.mql5.com/ru/docs/math/mathrand belgelerine aykırıdır

Alglib kaynakları arasında geçiş yapmak istemiyorum, ancak sinir ağı paketleri için NN ağırlıklarının rastgele bir değeriyle başlatma zorunludur, bunun MQL yardım materyaline göre yapıldığından şüpheleniyorum - yani. kullanılmış srand()

onlar. MQL programlarının test cihazı içinde böyle bir NS paketi ile kullanılması büyük olasılıkla bir işlemci çekirdeğinde gerçekleşecektir - ilk NS ağırlıkları aynı değerlere sahip olacak mı?

srand() olmadan daha da havalı

Igor, o halde MathSrand(int(GetMicrosecondCount()%16384)); deneyin.

resim nasıl değişecek merak ediyorum