MQL5'te OOP hakkında sorular - sayfa 16

 
Dmitry Fedoseev :

Standart kitaplık , kontrollerin form üzerinde oluşturulduğu anlamına gelir. Sadece hiç çalışmıyor gibi görünüyorlar. En azından eskiden böyleydi.

Grafik arayüzlerle ilgili bir dizi makaleden Kazharsky'nin en son sürümlerini denemek gerekecek. Ne kadar hızlı çalışıyor. Ve sonra yavrularını düzeltmek için geliştiricilere bir kez daha yazın.
 
Vasiliy Pushkaryov :
Grafik arayüzlerle ilgili bir dizi makaleden Kazharsky'nin en son sürümlerini denemek gerekecek. Ne kadar hızlı çalışıyor. Ve sonra yavrularını düzeltmek için geliştiricilere bir kez daha yazın.

herkes aynı daire içinde yürür! ))) - MQL'nin olanaklarını incelemeye başladığım grafik arayüzler hakkındaki bu makale dizisindendi .... - deneyim başarısız oldu, makalelerden bazı örnekler artık derlenmiyor, yazar iletişime geçiyor , ama kütüphanenin hacmi çok büyük, ben bu kütüphaneyi kullanmadım, mümkün olsa da

IMHO, ya bir hafta içinde C# çalışın - internette birçok örnek var ve VS'deki form tasarımcısı Delphi'dekiyle aynı (Delphi'de daha önce yazdım) ya da hala SB kullanıyor - en azından geliştiricilerden destek var

 
Igor Makanu :

herkes aynı daire içinde yürür! ))) - MQL'nin olanaklarını incelemeye başladığım grafik arayüzler hakkındaki bu makale dizisindendi .... - deneyim başarısız oldu, makalelerden bazı örnekler artık derlenmiyor, yazar iletişime geçiyor , ama kütüphanenin hacmi çok büyük, ben bu kütüphaneyi kullanmadım, mümkün olsa da

IMHO, ya bir hafta içinde C# çalışın - internette birçok örnek var ve VS'deki form tasarımcısı Delphi'dekiyle aynı (Delphi'de daha önce yazdım) ya da hala SB kullanıyor - en azından geliştiricilerden destek var

Bu kütüphanenin çoktan tamamlandığını duymak üzücü. Bir buçuk yıl önce denedim, panelin görüntüsünü beğendim. Hatta MT4 altında düzelttim ve denedim (Tuval'daki farklılıklar nedeniyle, bir şeyler de hemen derlenmedi), ama sonra evet, onu görevime taşımanın karmaşıklığı nedeniyle SB'yi aldım. GUI'lere daha sonra geri döneceğimi düşündüm.

C#'da bir haftada zar zor ustalaşabiliyorum. Ancak, özellikle .NET kitaplıkları için zaten yerel destek bulunduğundan, kendinize bu hedefi belirlemeniz gerekir. Böylece, özel göreviniz için nasıl kullanılabileceğini önerdiniz.

 
Vladimir Simakov :

Ve ikinci durumda,

 void   AddValue (T & value )  { Tptr  = value ; mlist.Add(Tptr);       }

nedense senin seçeneğinle işe yaramadı, belki yine batırdım)) ,

ama sonunda istediğim ortaya çıktı - verileri ara işaretçiler olmadan doğrudan listeye kaydetmek istiyorum, bellek sızıntısı olmadan bu şekilde çalışır:

 #property strict
#include <Arrays\List.mqh>
//+------------------------------------------------------------------+
template < typename T> class CDataBase
  {
private :
   CList            *mlist;
public :
   void CDataBase()           { mlist= new CList;                                    }
   void ~CDataBase( void )      { delete mlist;                                       }
   int ArraySize ( void )        { return (mlist.Total());                              }
   T operator []( int index)    { return (mlist.GetNodeAtIndex(index));                }
   void   AddValue (T value)   { mlist.Add(value);                                   }
   void   Delete( int pos)      { mlist.Delete(pos);                                  }
   string TypeName()          { return ( typename (T));                                }
  };

//+------------------------------------------------------------------+
class CData : public CObject
  {
public :
   int                x;
   double             y;
                     CData(){};
                     CData( int ival, double dval){x=ival;y=dval;}
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnStart ()
  {
   CDataBase<CData*>*data= new CDataBase<CData*>;
   int i;
   for (i= 0 ; i< 5 ; i++) data.AddValue( new CData(i,i* 2.0 ));
   Print ( "Тип БД : " , data.TypeName(), " б чтение данных :" );
   for (i= 0 ; i<data. ArraySize (); i++) Print (i, " : " ,data[i].x, " , " ,data[i].y);
   Print ( "Удалил № 3" );
   data.Delete( 3 );
   for (i= 0 ; i<data. ArraySize (); i++) Print (i, " : " ,data[i].x, " , " ,data[i].y);
   delete data;
  }
//+------------------------------------------------------------------+

bu benim fikrimin sadece başlangıcı

CData sınıfı alan şablonunu kullanarak bir dosyaya nasıl yazacağımı bulana kadar uygulamak için şablonumdaki bir ikili dosyaya yazmak ve okumak istiyorum (bir metin dosyasına da yazabilseniz de - önemli değil) - ancak Gerçekten istiyorum! ;)

 
Igor Makanu :

CData sınıfı alan şablonunu kullanarak bir dosyaya nasıl yazacağımı bulana kadar uygulamak için şablonumdaki bir ikili dosyaya yazmak ve okumak istiyorum (bir metin dosyasına da yazabilseniz de - önemli değil) - ancak Gerçekten istiyorum! ;)

 #property strict
#include <Arrays\List.mqh>
//+------------------------------------------------------------------+
struct FILE
{
   const int handle;
  
  FILE( const string FileName, const int Flags ) : handle(:: FileOpen (FileName, Flags)) {}  
  ~FILE( void ) { if ( this .handle != INVALID_HANDLE ) :: FileClose ( this .handle); }
};

template < typename T>
class CList2 : public CList
{
public :  
   virtual CObject  *CreateElement( void ) { return ( new T); }
};

template < typename T> class CDataBase
  {
private :
   CList2<T>             *mlist;
public :
   void CDataBase()           { mlist= new CList2<T> ;                                    }
   void ~CDataBase( void )      { delete mlist;                                       }
   int ArraySize ( void )        { return (mlist.Total());                              }
   T* operator []( int index)    { return (mlist.GetNodeAtIndex(index));                }
   void   AddValue (T * value)   { mlist.Add(value);                                   }
   void   Delete( int pos)      { mlist.Delete(pos);                                  }
   string TypeName()          { return ( typename (T));                                }
   bool Save( const string FileName ) const { const FILE File(FileName, FILE_WRITE | FILE_BIN ); return ( this .mlist.Save(File.handle)); }
   bool Load( const string FileName ) { const FILE File(FileName, FILE_READ | FILE_BIN ); return ( this .mlist.Load(File.handle)); }

  };

//+------------------------------------------------------------------+
class CData : public CObject
  {
public :
   int                x;
   double             y;
                     CData(){};
                     CData( int ival, double dval){x=ival;y=dval;}
   virtual bool       Save( const int file_handle ) { return (:: FileWriteInteger (file_handle, this .x) && :: FileWriteDouble (file_handle, this .y)); }
   virtual bool       Load( const int file_handle )
   {
     :: ResetLastError ();
     
     this .x = :: FileReadInteger (file_handle);
     this .y = :: FileReadDouble (file_handle);
     
     return (!:: GetLastError ());
   }
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnStart ()
  {
   CDataBase< CData >*data= new CDataBase<CData>;
   int i;
   for (i= 0 ; i< 5 ; i++) data.AddValue( new CData(i,i* 2.0 ));
   Print ( "Тип БД : " , data.TypeName(), " б чтение данных :" );
   for (i= 0 ; i<data. ArraySize (); i++) Print (i, " : " ,data[i].x, " , " ,data[i].y);
   
   data.Save( "Data.bin" );
   delete data;

   CDataBase<CData> data2;   
   data2.Load( "Data.bin" );
   Print ( "Тип БД : " , data2 .TypeName(), " б чтение данных :" );
   for (i= 0 ; i< data2 . ArraySize (); i++) Print (i, " : " , data2 [i].x, " , " , data2 [i].y);
  }
//+------------------------------------------------------------------+

CList ve CObject ile hiç çalışmadım, ancak kaynaklar basit (bu arada, bir nedenden dolayı const değiştiricisi olmayan sanal bir Save yöntemi var), bu yüzden hemen çalıştı.


PS Böyle yazmak daha kolay

 template < typename T> class CDataBase
  {
private :
   CList2<T>            mlist; // Объект, не указатель

O zaman yapıcı/yıkıcı gerekli değildir. yeni/sil gerçekten yararlı olduğu yerde kullanmak hala mantıklı. Aksi takdirde, yukarıdaki DOSYA ile aynı şeyi yapabilirsiniz.

 
fxsaber :

CList ve CObject ile hiç çalışmadım, ancak kaynaklar basit, bu yüzden hemen işe yaradı.

Ö! çok hızlı yanıt aldı! - TEŞEKKÜR EDERİM! - gece yapılacak bir şey.

Ayrıca CList ve CObject kaynaklarını da okudum, herhangi bir sorun görmüyorum ancak testlerin yapılması gerekiyor.

Not: burada, genel olarak, almak istediğim şey ... peki, evrensel bir liste gibi görünüyor:

1. Oluşturulduktan hemen sonra yapı sınıfları ekleyebileceğiniz (uygulandı - örnek verilerimi kontrol ettim.AddValue(new CData(i,i*2.0)) - OK)

2. İçinde bir dosyaya yazıp "DB" dosyasından okuyabileceğiniz (Şablon kurucusu bunu görünce yazmaya başladım)

 1 . void CDataBase()           { mlist= new CList; m_file_handle= INVALID_HANDLE ;         }
2 . void CDataBase( int BaseID) { mlist= new CList;m_id=BaseID;m_file_handle=fileopen();  }

1 ve 2 numaralı dosyaya yazmadan/okumadan çalışıyoruz diskten CDataBase oluştururken veritabanını okuyoruz, yıkıcı çağırırken diske yazarken

....

not:

Peki, tüm bunlar neden? - Danışmanları standart şemaya göre yazıyorum - sihir ve sihirle bir sipariş arayarak emirlerle tüm manipülasyonlar, eğer TS "101 göstergeye" göre değilse, ancak daha karmaşıksa, genellikle 2 sihir yeterlidir, ANCAK 80 bekleyen siparişi takip eden TS (10 sipariş ızgarası, ızgaralar yeniden açıldı ve ... dürüst olmak gerekirse, saçma bir TS, ancak bununla ikinci kez karşılaştım), sonra çeşitli hileler başlıyor - 80 için 80 sipariş çalıştırıyorum üretilen sihirler))) - Çıktım ama tüm bunlardan hoşlanmıyorum

bu yüzden sonunda, siparişler hakkında (evet, herhangi bir şey) veri yazabileceğiniz küçük bir veritabanı yapmak istiyorum ve asıl şey veritabanının kendisine hiç dikkat etmemek - dizi öğelerine erişim, bir dosyaya okuma ve yazma danışmanı başlatırken veya kapatırken

böyle bir şey)))


fxsaber :

PS Böyle yazmak daha kolay

O zaman yapıcı/yıkıcı gerekli değildir. yeni/sil gerçekten yararlı olduğu yerde kullanmak hala mantıklı. Aksi takdirde, yukarıdaki DOSYA ile aynı şeyi yapabilirsiniz.

Teşekkürler, ama yine de bunun hakkında düşünmeniz gerekiyor ... veya daha doğrusu, gelecekte düşünmemek için yapmak istiyorsunuz))) - OnInit()'te bir veritabanı oluşturdular, dosyayı okudu, DeInit()'te veritabanını öldürdüler, dosyayı yazdı ve DeInit()'de silmeyi kaçırdıysanız, o zaman terminalin kendisi bunu günlüğe kaydeder... bence bu, veritabanıyla çalışırken hataları ortadan kaldırır. ..genel olarak yaparsam ne kadar uygun olduğu görülecektir.

 
fxsaber :
 virtual bool       Load( const int file_handle )
   {
     :: ResetLastError ();
     

zorlaştırmıyorsa, neden burada "::" kullanıyorsunuz https://www.mql5.com/en/docs/basis/operations/other

 
Igor Makanu :

zorlaştırmıyorsa neden burada "::" kullanıyoruz

Aksi takdirde, ebeveyn sınıflarında aynı isimde bir yöntem olmadığını kontrol etmem gerekecek. Ve olmasa bile, biri onu eklerse kod çalışmaya devam eder.

Aynı nedenden dolayı, bunu her zaman belirsizlik ve okunabilirlik için kullanırım.


ZY Ancak bazı nadir durumlarda :: ve bu esneklikten mahrumdur. Yöntem gövdesini sınıfın içine ve ne zaman - dışarıda yazmanın daha iyi olduğu konusunda benzer incelikler vardır. Bütün bunlarla karşılaştığımı hatırlıyorum ama örnek vermeyeceğim.

 
fxsaber :

Aksi takdirde, ebeveyn sınıflarında aynı isimde bir yöntem olmadığını kontrol etmem gerekecek. Ve olmasa bile, biri onu eklerse kod çalışmaya devam eder.

Aynı nedenle, bunu her zaman belirsizlik ve okunabilirlik için kullanırım.

Evet gerçekten pratik ve bug görünümünü ortadan kaldırıyor, hizmete alacağım

Teşekkür ederim!

 
Igor Makanu :

4. m_fsave dosyasına yazma bayrağı etkinse, AddValue() yöntemini her çağırdığımızda dosyaya yazarız

CList kayıt formatına bakın. Onu görmezden geliyorsun.