dinamik olarak nesneler nasıl oluşturulur? (Bazı OOP şeyler) - sayfa 2

 
Doerk Hilger :

Tamamen yanlış yaptığınızı söylemek istemiyorum ama yapıyorsunuz, çünkü bu yapı programlaması ve OOP değil. En büyük fark, kalıtımın ve aşırı yüklemenin gücüdür. Bu arada, gerçek grafik nesnelerinden gerçekten miras alamazsınız, ancak herhangi bir şeyi bir kod nesnesi olarak temsil edebilir ve bu nesneden bir satıra veya herhangi bir şeye başvurabilirsiniz. MFC veya MQL sınıfı olsun, herhangi bir sınıfta genellikle böyle yapılır, hepsi aynıdır.

Çizgileriniz nesnelerse, onlara öyle davranın. Dışarıdaki dizilerle uğraşmayın, bunu bir sınıf koleksiyonu içinde yapın ve işaretçilerle çalışın. CWndContainer'a bir göz atın ve onun hakkında bir fikir edinin. Bu sınıf, esas olarak CWnd nesneleri için işaretçi dizilerini yöneten bir kapsayıcıdır. Bir adım ileri gidin, yapınız şöyle olmalıdır:

Her nesne için temel olarak CObject

Çizgiler gibi her fiyat/zamana dayalı nesne için temel olarak CPriceTimeObjects, CObject'den türetilmiştir. Oluşturmayı kontrol eder, zamanı ve fiyatı tutar ve bir sonraki mirasçı tarafından kullanılabilecek bir OnCreate() çağırır. Ayrıca, mirasçılar tarafından aşırı yüklenen sanal OnTick()'i çağıran bir Tick işlevine de sahiptir.

Trend çizgileri için temel olarak CTrendLine, CPriceTimeObjects öğesinden miras alır ve ObjectCreate işlevini kullanarak son satırı oluşturduğu OnCreate öğesini işler. Ayrıca Tick olaylarına tepki vermek/cevap vermek için bir OnTick() işleyicisine sahip olmalıdır, çünkü anladığım kadarıyla fiyata duyarlı olacaktır.

Bunun yanı sıra, istediğiniz tüm CTimePriceObject nesnelerini tutan bir işaretçi dizisini yöneten bir kapsayıcı sınıfınız var, kendisini CTimePriceObject'ten de devralır ve OnTick()'i "childs" e geçirir. Kap, ayrıca satır eklemek veya satırları kaldırmak için OnChartEvent()'i işleyen bir işleve sahiptir. Ayrıca, vaka için mevcut tüm nesneleri taramak için bir tarama işlevine sahip olmalıdır, satırlar oluşturulduktan sonra uzman eklendi. Ayrıca, CTimePrice'den aşırı yüklenmiş OnTick()'i işler, diziyi orada döngüler, içindeki her CTrendLine nesnesine, sanal bir OnTick tarafından işlenen her alt nesnenin Tick işlevini çağırarak tepki vermekten bir şekilde sorumlu olup olmadığını sorar. Neden bu tekrar? CTrendLine bu işlevi CTimePrice'den de aşırı yüklediğinden ve bu şekilde bu sınıf, başka işlevlere sahip diğer mirasçılar tarafından da devralınabilir.

Çok güzel, Dorek.

Yine de bazı sorularım var:

CTimePriceObject'i tutan kapsayıcı neden kendisini CTimePriceObject'ten devralmak zorunda? Örnek için, standart lib'deki CIndicators, CArrayObj'den devralır ve büyük olasılıkla, devralmadan CIndicator'a atıfta bulunur.
Normal dizileri değil standart lib'i kullanmak istediğini biliyorum, ancak belirli türden bir nesne kabının nesnenin kendisini devralması gerektiği kavramı hakkında bir şey benim için net değil (çünkü kap, içerdiği bir nesne değil, yani "bir" ilişkisi yoktur) doğru olduğunu düşünmeme rağmen.
Bu konudaki görüşünüzü açıklar mısınız?

İkincisi, CTrendLine'ın dilin yerel ObjectCreate işlevini kullanarak son satırı oluşturduğunu söylerken standart kitaplığa güvenmeden sıfırdan çerçeve oluşturuyor gibisiniz.
Standart kitaplıkların kendilerini genişletmeyi ne zaman önerirsiniz, örneğin, standart lib'deki tüm CIndicator nesnelerinin, fiyatın içlerinde bir arabelleğe kaç kez dokunduğunu söyleyebilmesini istediğimi varsayalım.
son X çubuklarında. Bunu nasıl devam ettirirsiniz, çünkü CIndicator veya CIndicatorBuffer gibi bir temel sınıfı genişletirseniz, standart kitaplığın tüm bağımlı nesnelerine sahip olduğunuzdan,
örneğin CiMA gibi yeni CIndicator veya yeni CBuffer. Tüm bu özel gösterge sınıflarını klasörünüze kopyalar ve devralmalarını yeni CIndicatorBuffer'ınıza değiştirir misiniz? peki ya meta alıntılar standart CIndicatorBuffer veya üst sınıflarına bir şeyler eklerse?

Anlayışlar için çok teşekkür ederim.

BR

 

Willbur :

...

Bu yöne gittiğinizde SmartLine nesnem MT5 menüsünde trend çizgisinin, okların, metin nesnesinin ve tüm bu şeylerin yanında görünmelidir.

...

MT5 buna izin veriyorsa, ancak o zaman kalan soruyu, fiyat değiştiğinde nesnenin terminal programı tarafından nasıl tetiklenebileceğini tartışmalıyız.

...
Bunu mql5 ile yapamazsınız.
 
Amir Yacoby :

Çok güzel, Dorek.

Yine de bazı sorularım var:

CTimePriceObject'i tutan kapsayıcı neden kendisini CTimePriceObject'ten devralmak zorunda? Örnek için, standart lib'deki CIndicators, CArrayObj'den devralır ve büyük olasılıkla, devralmadan CIndicator'a atıfta bulunur.
Normal dizileri değil standart lib'i kullanmak istediğini biliyorum, ancak belirli türden bir nesne kabının nesnenin kendisini devralması gerektiği kavramı hakkında bir şey benim için net değil (çünkü kap, içerdiği bir nesne değil, yani "bir" ilişkisi yoktur) doğru olduğunu düşünmeme rağmen.
Bu konudaki görüşünüzü açıklar mısınız?

İkincisi, CTrendLine'ın dilin yerel ObjectCreate işlevini kullanarak son satırı oluşturduğunu söylerken standart kitaplığa güvenmeden sıfırdan çerçeve oluşturuyor gibisiniz.
Standart kitaplıkların kendilerini genişletmeyi ne zaman önerirsiniz, örneğin, standart lib'deki tüm CIndicator nesnelerinin, fiyatın içlerinde bir arabelleğe kaç kez dokunduğunu söyleyebilmesini istediğimi varsayalım.
son X çubuklarında. Bunu nasıl devam ettirirsiniz, çünkü CIndicator veya CIndicatorBuffer gibi bir temel sınıfı genişletirseniz, standart kitaplığın tüm bağımlı nesnelerine sahip olduğunuzdan,
örneğin CiMA gibi yeni CIndicator veya yeni CBuffer. Tüm bu özel gösterge sınıflarını klasörünüze kopyalar ve devralmalarını yeni CIndicatorBuffer'ınıza değiştirir misiniz? peki ya meta alıntılar standart CIndicatorBuffer veya üst sınıflarına bir şeyler eklerse?

Anlayışlar için çok teşekkür ederim.

BR

1. Konteynerin kalıtımı.

MQL'nin bir sınırlaması, birden fazla mirasa sahip olamamanızdır. Bu nedenle, bir kişinin en az bir ölümle ölmesi gerekir. Elbette haklısınız, CArrayObj'den kalıtım almak da mantıklı olurdu, ancak bunu yapmazdım, çünkü kap, herhangi bir CTimePrice nesnesinin işlediği tüm olayları, örneğin Tick()->OnTick()'i işler ve bunları dağıtır. bir dizi nesnesinin bununla hiçbir ilgisi yoktur. Aynı temel sınıftan miras alan diğer nesneleri de tutan bir kapsayıcı nesnesi, yalnızca daha fazla ortak noktaya sahiptir. Böyle bir konteynır aynı zamanda bir fiyata ve zamana bağlı olarak bir çapaya da sahip olabilir ve böyle bir konteynırı hareket ettirdiğinizde/değiştirdiğinizde, tüm "çocuklarını" taşımak da konteynırın işi olacaktır. Bu sadece bir örnek, ancak bu tür fikirlerin listesi muhtemelen dizi işlevleri hakkındaki fikirlerin listesinden daha uzundur.

Ve evet, aynı zamanda böyle, bu tür nesnelerin birçok türüyle ilgilenen bu tür sınıfları gerçekten yarattım ve bu arada edindiğim deneyim bana, bu şekilde devralmayı yönetmenin doğru karar olduğunu söylüyor.

2. Sıfırdan çerçeve.

Burada benzer. Standart kütüphanelerde biraz daha derine inmeye başladığımda, sevmediğim birçok şey buldum. Sadece bunların kötü performansı değil, aynı zamanda esneklik eksikliği ve eksik bir mimari nedeniyle. Örneğin, CWnd ve CObject arasındaki bir sınıfın yanı sıra global bir CMouse sınıfını/nesnesini de özlüyorum, çünkü CWnd nesneleri, çizgilerin yanı sıra grafiğin çocuklarıdır ve böyle bir bağlantı yoktur ve bu tür nesnelerin hiçbir nihai uygulaması yoktur. tamamen yukarıda anlattığım gibi. Ve tüm bu tür grafik nesnelerini tutan, hepsini tek bir komutla göstermeyi/gizlemeyi, yok etmeyi mümkün kılan bir ana nesne yoktur. CCanvas, aynı şey, güzel bir sınıf ama CWnd'den miras kalan bitmap'lere dayalı etkileşimli nesneler oluşturmama izin veren CWnd ile uygulama nerede? Ve benzeri.

Ayrıca, tüm standart kitaplıkların tüm yapısı yan zincirlere izin vermez, ancak bu gereklidir, çünkü MQL boşluk işaretçilerine izin vermez. Örneğin: Sürüklenebilen trend çizgisi nesneleri oluşturmama izin veren, CDragLine adlı bir sınıf kullanıyorum. Böyle bir trend çizgisi nesnesi bir siparişe ve ayrıca bir panele/ekrana bağlıysa, bağlı panelin de sipariş değişikliklerinin neden olduğu hareketler/değişiklikler hakkında bilgi alacağı bir yan zincir kullanma olasılığına ihtiyacım var. . Ve tam tersi, sırayı taşıma ve satırın kendisi sürüklendiğinde paneli bilgilendirme seçeneğine ihtiyacım var. Bu tür üçgen mesajlaşma standart kütüphane ile yapılamaz. Bu, yan zincirler tarafından yapılır; bu, kesinlikle tüm nesnelerin gelişmiş bir CObject sürümünden miras aldığı anlamına gelir. Bu sınıf, başka herhangi bir nesneyi bir nesneye bağlama ve böyle bir bağlı nesneye mesaj gönderme olanağına sahiptir. Bu şekilde, herhangi bir garip kod olmadan çok daha karmaşık ve etkili bir mesajlaşma mümkündür.

Herkesin ne yapması gerektiğine dair herhangi bir tavsiyede bulunamam, ama aslında standart kitaplıkların %99'unu bırakmaya karar verdim, orijinallerden kalan tek sınıflar CCanvas (ancak bazı değişiklikler ve hata düzeltmeleri ile, bkz. Kod Tabanı) ) ve CSymbolInfo.

--------------

Birisi yan zincir işleviyle ilgileniyorsa, işte CObject sınıfımın kodu. Her güncellemeden sonra orijinal CObject'i Object.mqh'de değiştirirseniz, standart kitaplıkların çoğu bölümü bu yan zincir özelliğinin geliştirmelerini alır. Ve bu arada, düğüm bağlantısı da uygulanır - bu orijinalde yapılmaz.

Böyle bir yan zincir özelliği eklemek için alıcı sınıfın içinde aşağıdaki gibi yapın:

 //--- Example for receiving class
//---

class CAnyClass : public CAnyBaseClass // of course CAnyBaseClass inherits from CObject in the end too
   {
   private :
      CWhatEver   m_object;     // embedded object
      CFurther    m_further;    // embedded object

   public :
   //+------------------------------------------------------------------+
   //|  Creation                                                        |
   //+------------------------------------------------------------------+
   CAnyClass( void )
      {
      m_classname= " CAnyClass " ; 

       //--- Connect side chains 
      m_object.CustomEventReceiver(PTR( this ));
      m_further.CustomEventReceiver(PTR( this ));
      }
   
   protected :
   //+------------------------------------------------------------------+
   //|  Custom event handler for side chain messages                    |
   //+------------------------------------------------------------------+
       virtual void       OnCustomEvent(CObject * sender, int eventid)
         {
             if (sender==PTR(m_object))
               {
               switch (eventid)
                  {
                   case 123456 :
                     Print ( "Here we go with 123456" );
                     break ;
               //...
                  }
               }
             else if (sender==PTR(m_further))
               {
               //...
               } 
         }            
   };

Gönderen sınıflar CWhatEver ve CFurther, alıcı hakkında bir alıcı olup olmadığı hakkında hiçbir şey bilmiyor. Kod sadece aşağıdaki gibidir:

 //---
//...

   CustomEvent( 123456 );

//...
//---

İşte CObject değişimi:

 //+------------------------------------------------------------------+
//|                                                       Object.mqh |
//|                                               Copyright by Doerk |
//+------------------------------------------------------------------+

#ifndef __DH_OBJECT_CLASS
#define __DH_OBJECT_CLASS

#include <stdlib.mqh>
//+------------------------------------------------------------------+
//|                                                                  |
//| Defintions                                                       |
//|                                                                  |
//+------------------------------------------------------------------+
#ifndef PTR
   #define PTR(object) GetPointer (object)
   #define PTR_DELETE(object) { if ( CheckPointer (object)== POINTER_DYNAMIC ) delete object; }
   #define PTR_INVALID(object) (object== NULL || CheckPointer (object)== POINTER_INVALID )
#endif   

enum ENUM_FILE_IO
   {
   FILE_IO_NONE = 0 ,     //--- No file interaction
   FILE_IO_BINARY = 1 ,   //--- Binary, OnLoad() / OnSave() events
   FILE_IO_INI = 2 ,     //--- Ini file, OnLoadIni() / OnSaveIni() events
   };
   
//+------------------------------------------------------------------+
//|                                                                  |
//| Class CStruct - the base of everything                           |
//|                                                                  |
//+------------------------------------------------------------------+
class CStruct
   {
   };
//+------------------------------------------------------------------+
//|                                                                  |
//| Class CObject                                                    |
//|                                                                  |
//+------------------------------------------------------------------+
class CObject : public CStruct
  {
   protected :      
       long               m_obj_id;               //--- Unique ID of each object
       string             m_classname;             //--- Name of (deriving) class
      CObject          *m_prev;                 //--- Previous item in chain
      CObject          *m_next;                 //--- Next item in chain
      CStruct          *m_struct;               //--- Additional attached struct
      CObject          *m_object;               //--- Additional attached object
       string             m_tag;                   //--- Additional tag (File operation)
   private :
      CObject          *m_eventreceiver;         //--- Object which gets custom notifications
      ENUM_FILE_IO      m_fileio;               //--- Enables/disable file input/output
      
   public :
       //+------------------------------------------------------------------+
       //| Construction                                                     |
       //+------------------------------------------------------------------+
      CObject( void ) : m_fileio(FILE_IO_BINARY),
                      m_struct( NULL ),
                      m_tag( NULL ),
                      m_object( NULL )
         {
       //--- Set ID
            __obj_cnt++;
            m_obj_id=__obj_cnt;
       //--- Reset notified object            
            m_eventreceiver= NULL ;
       //--- Connect chain            
            Prev(__obj_prev);
             if (__obj_prev!= NULL )
               __obj_prev.Next(PTR( this ));
            __obj_prev=PTR( this );
            Next( NULL );
            
         } 
         
       //+------------------------------------------------------------------+
       //| Destruction                                                      |
       //+------------------------------------------------------------------+
      ~CObject( void )
         {
       //--- Reconnect chain
             if (m_prev!= NULL )
               m_prev.Next(m_next);
             if (m_next!= NULL )
               m_next.Prev(m_prev);    
             if (__obj_prev==PTR( this ))
               __obj_prev=Prev();                    
         } 
       //+------------------------------------------------------------------+
       //| Chain access                                                     |
       //+------------------------------------------------------------------+
   public :      
      CObject          *Prev( void )                                       const { return (m_prev); }
       void               Prev(CObject *node)                                   { m_prev=node;    }
      CObject          *Next( void )                                       const { return (m_next); }
       void               Next(CObject *node)                                   { m_next=node;    }
       //+------------------------------------------------------------------+
       //| Custom events - allows interaction between embedded objects and  |
       //|                containers                                        |
       //+------------------------------------------------------------------+
   public :
      CObject *         CustomEventReceiver( void )                       const { return (m_eventreceiver); }
       bool               CustomEventReceiver(CObject *receiver)
         {
             if (m_eventreceiver!= NULL )
               return false ;
            m_eventreceiver=receiver;
             return true ;   
         }
       void               CustomEvent( int eventid= 0 )
         {
             if (!PTR_INVALID(m_eventreceiver))
               m_eventreceiver._CustomEvent(PTR( this ), eventid);
         }      
       void               _CustomEvent(CObject * sender, int eventid)
         {
            OnCustomEvent(sender, eventid);
         }      
   protected :
       virtual void       OnCustomEvent(CObject * sender, int eventid)         
         {
         }
                                          
       //+------------------------------------------------------------------+
       //| File interaction                                                 |
       //+------------------------------------------------------------------+
   public :
       bool               Save( const int file_handle)                           { if (m_fileio==FILE_IO_NONE) return true ; return (OnSave(file_handle));   }
       bool               Load( const int file_handle)                           { if (m_fileio==FILE_IO_NONE) return true ; return (OnLoad(file_handle));   }
       bool               Save(CObject *fileobject)                             { if (m_fileio==FILE_IO_NONE) return true ; return (OnSave(fileobject)); }
       bool               Load(CObject *fileobject)                             { if (m_fileio==FILE_IO_NONE) return true ; return (OnLoad(fileobject)); }
       bool               LoadDefault( void )                                     { return (OnLoadDefault()); }
       bool               FileIO( const ENUM_FILE_IO flag)                       { m_fileio=flag; return true ; }
      ENUM_FILE_IO      FileIO( void )                                          { return m_fileio; }
   protected :
       virtual bool       OnSave( const int file_handle)                         { return true ; }
       virtual bool       OnLoad( const int file_handle)                         { return true ; }
       virtual bool       OnSave(CObject *fileobject)                           { return true ; }
       virtual bool       OnLoad(CObject *fileobject)                           { return true ; }
       virtual bool       OnLoadDefault( void )                                   { return true ; }
      
       //+------------------------------------------------------------------+
       //| Identification                                                   |
       //+------------------------------------------------------------------+
   public :      
       long               Id( void )                                         const { return m_obj_id;    }
       virtual int        Type( void )                                       const { return ( 0 );      }
       string             ClassName( void )                                 const { return (m_classname); }
       string             Tag( void )                                       const { return m_tag; }
       bool               Tag( string value)                                     { m_tag=value; return true ; }

       //+------------------------------------------------------------------+
       //| Comparison                                                       |
       //+------------------------------------------------------------------+
   public :      
       virtual int        Compare( const CObject *node, const int mode= 0 )   const { return ( 0 );      }
      
  };
//+------------------------------------------------------------------+
long __obj_cnt=- 1 ;
CObject * __obj_prev= NULL ;
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+

#endif                   // __DH_OBJECT_CLASS
 

Yan zincir fikrini detaylandırdığınız ve paylaştığınız için teşekkür ederiz.

Açıkçası, tam olarak anlamıyorum ve kod derlenmiyor (CWhatEver ve CFurther'ı boş sınıflar olarak yarattım, sadece fikri elde etmek için sadece kurucu ile gönderdiğiniz CObject'i doğrudan miras aldım).

CWhatEver::CWhatEver hakkında alınan 2 derleme hatası özel üye işlevini çağıramaz ve CFurther için aynı hata.

Her neyse, "yan zincir" terimini google'da aradım ve bulamadım. Okuyabileceğim bazı yazılı materyaller biliyorsanız, harika olurdu.

BR

 

Evet sınıflar boş, bu yüzden derlenmiyorlar. Bunlar sadece yer tutucular.

Yan zincirler bunun resmi açıklaması olmayabilir, bunun yerine geçersiz işaretçiler ve/veya çoklu kalıtım için temiz MQL geçici çözümüm. Kısacası: Size herhangi bir sınıf arasında iletişim kurma yeteneği verir ve nesneler sınıflara gömülüyse çok yararlıdır, çünkü onlara içeren sınıfın kendi özel olaylarının alıcısı olduğunu "söyleyebilirsiniz". Bu şekilde herhangi bir spagetti kodlamasını önleyebilirsiniz.

Örneğin, şöyle bir şeyiniz varsa

OnClick()'i döndür;

bu, ilk önce son türetilen sınıfın aşırı yüklenmesini çağırır, onu şöyle bir şeye genişletebilirsiniz.

dönüş OnClick()&CustomEvent(CUSTOM_CLICK);

Bu şekilde, yalnızca normalde bir

sanal bool OnClick()

işlev bildirilir, ayrıca nesneyi içeren sınıf da tıklama bildirimini alabilir.

 

Bunun, mesaj gönderdiği diğer nesneyi bilmesi gereken normal mesajlaşma yoluyla değil, özel olaylar aracılığıyla herhangi iki nesne arasında iletişim kurmanın bir yolu olduğunu mu kastediyorsunuz?

Bu fikri anladım, ama gömülü nesnelerle ne demek istiyorsun? CAnyClass kodunuzda iki özel nesneniz vardı. Gömülü ile vücutlarının da içeride etiketlenmesi gerektiğini mi kastediyorsunuz?
CAnyClass veya bunlar dışında tanımlanabilir mi? Demek istediğim, terimi kullandığınız gibi gömülü, başka bir nesnenin içinde özel olan bir nesne mi?

Örneğin, CAnyClass dışında CWhatEver yazarsam ve bir olay hakkında CAnyClass'a mesaj göndermek istersem, CWhatEver'da geri döneceğimi mi kastediyorsunuz?

dönüş OnClick()&CustomEvent(CUSTOM_CLICK); // <=== & yerine && demek istedin ????

hangisi her zamanki gibi CWhatEver'ın türetilmiş sınıfına ve ayrıca CAnyClass olan (özel olay nedeniyle) içeren sınıfa mesaj gönderir?

Ve neden CObject bir #ifndef içinde tanımlanmış?

BTW, sadece merak ediyorum, CObject'inizdeki stdlib.mqh'nin amacı nedir?

 

Aşağıdan yukarıya...

- stdlib, yine de orijinal object.mqh dosyasına dahil değil mi? Burada buna ihtiyacım yok, ancak iki çifti karşılaştırmanın tek güvenilir yolu olan CompareDouble() içeriyor.

- Standart ve koşullu derleme için çift tanımları önlemek için #ifndef kullanıyorum

- evet, üçgen mesajlaşma için

- ikili & ve mantıksal sürüm &&, bool sonuçlarıyla aynıdır

- gömülü ile demek istediğim, yabancı bir sınıfın örneği/nesnesi başka bir sınıfın parçasıysa ve her ikisi de birbirinden türemiyorsa. OnClick() örneğini kullanın ve m_object'in OnClick()'i bir şekilde dahili amaçlarla, örneğin bir düğme ya da her neyse, işlediğini varsayın. Bu özel olay olmadan bir tıklama olduğunu CAnyClass içinde bilmeniz gerekiyorsa, kod nasıl görünür?

Dürüst olmak gerekirse, her gün her amaç için ihtiyaç duyulan bir işlevsellik değil, ancak yalnızca yönlü değil, iletişim kurmanız gereken bir durum varsa, çözüm.

Orijinal iş parçacığı sorununa geri dönün. Fikir, fiyata tepki veren birden çok satırı yönetmek için dizileri kullanmaktı. Bu çizgi nesneleri, çizgileri bir mum tarafından geçtiğinde olayları işler ve bazı eylemleri zorlar. Bir kap kullanmanızı tavsiye ettim. Bu kapsayıcı şimdi bu eylemleri saymak istiyorsa, örneğin, kapsayıcı her nesneye örneğin kullanarak özel olayın alıcısı olduğunu söylediğinde bu şekilde kolayca yapılabilir.

m_trendline[n].CustomEventReceiver(PTR(bu));

CTrendLine sınıfı - elbette - bunu bir şekilde şu şekilde uygulamak zorundadır:

dönüş OnLineCrossed()&CustomEvent(CTRENDLINE_CROSSED);

 
Vay be , forumda böyle bir tartışmanın olması ne güzel . Yine de hala OOP'nin başında olduğumu itiraf etmeliyim . _

Ne yazık ki, iki haftalığına tatile gidiyorum . P şeridi saat içinde ayrılıyor ( tamam , daha kötü olabilirdi ) .

Bu noktada zaten bir sorum var : MQL çerçeve çalışması hakkında ayrıntılı bir belge var ?


Willbur
 
Willbur :
..

Bu noktada zaten bir sorum var : MQL çerçeve çalışması hakkında ayrıntılı bir belge var ?

Numara :-(

Tecrübelerime göre, "mql çerçevesini" incelemeyi öğrenmek güzel. Ama Doerk'in de belirttiği gibi Standard Library ile ilgili çok fazla sorun var ve bence ciddi ve büyük projelerde kullanılamıyor.

 
Doerk Hilger :

Aşağıdan yukarıya...

- stdlib, yine de orijinal object.mqh dosyasına dahil değil mi? Burada buna ihtiyacım yok, ancak iki çifti karşılaştırmanın tek güvenilir yolu olan CompareDouble() içeriyor.

- Standart ve koşullu derleme için çift tanımları önlemek için #ifndef kullanıyorum

- evet, üçgen mesajlaşma için

- ikili & ve mantıksal sürüm &&, bool sonuçlarıyla aynıdır

- gömülü ile demek istediğim, yabancı bir sınıfın örneği/nesnesi başka bir sınıfın parçasıysa ve her ikisi de birbirinden türemiyorsa. OnClick() örneğini kullanın ve m_object'in OnClick()'i bir şekilde dahili amaçlarla, örneğin bir düğme ya da her neyse, işlediğini varsayın. Bu özel olay olmadan bir tıklama olduğunu CAnyClass içinde bilmeniz gerekiyorsa, kod nasıl görünür?

Dürüst olmak gerekirse, her gün her amaç için ihtiyaç duyulan bir işlevsellik değil, ancak yalnızca yönlü değil, iletişim kurmanız gereken bir durum varsa, çözüm.

Orijinal iş parçacığı sorununa geri dönün. Fikir, fiyata tepki veren birden çok satırı yönetmek için dizileri kullanmaktı. Bu çizgi nesneleri, çizgileri bir mum tarafından geçtiğinde olayları işler ve bazı eylemleri zorlar. Bir kap kullanmanızı tavsiye ettim. Bu kapsayıcı şimdi bu eylemleri saymak istiyorsa, örneğin, kapsayıcı her nesneye örneğin kullanarak özel olayın alıcısı olduğunu söylediğinde bu şekilde kolayca yapılabilir.

m_trendline[n].CustomEventReceiver(PTR(bu));

CTrendLine sınıfı - elbette - bunu bir şekilde şu şekilde uygulamak zorundadır:

dönüş OnLineCrossed()&CustomEvent(CTRENDLINE_CROSSED);

stdlib Sadece MQL4 olduğunu sanıyordum ama belki yanılıyorum.
Üzgünüm, tüm CObject'in neden #ifndef içinde olması gerektiğini anlamadım. Düz yazılırsa çift tanımlı ne olur? Ve btw, neden CStruct'u CObject'in üzerine boş sınıf olarak koydunuz?

Gömülü sınıf hakkında, (üzgünüm ben de 25 yıldır programcıyım ama OO değil) örneğiniz örneğin böyle bir duruma mı atıfta bulunuyor? Bir CCar sınıfı olduğumu ve bir CWheel sınıfını yerleştirdiğimi varsayalım.
Ve CWheel'in minimum hava basıncı veya benzeri bir olay işleyicisi var ve araba olarak bunu bilmem gerekiyor mu?
Bu örneğe veya başka bir spesifik örneğe benzerlikler bulabilirseniz, çünkü hala hangi sınıfın olayları tetiklediği (tıklama ile verdiğiniz örnekte bu açıkça tablodur) ve kimin ele aldığı konusunda tam olarak orada değilim. Ve hatta teknik olarak, örneğin bu satırları anlamak (amacının, konteynerin fiyatı bir çubukla geçen trend çizgilerini yönetme işini nasıl yapacağını göstermek olduğunu varsayıyorum):

m_trendline[n].CustomEventReceiver(PTR(bu));
doğru anladıysam açıklarmısın bir döngüdeki tüm eğilim çizgilerini [1..n] olarak mı adlandırıyor? eğer öyleyse, konteynerin şu anda işlemekte olması ne tür bir genel olay olabilir? çizgi değil
tüm hatları çağırdığı için belirli bir olay. CTRENDLINE_CROSSED olayını tetikleme potansiyeli olan yeni bir çubuk veya fiyat değişikliği gibi olabilir mi? Ve neden her satıra GetPointer(this) gönderiyor?
hattın kapsayıcıyı geri araması gerekiyor mu ve neden?
Öyleyse, eğer durum buysa,

dönüş OnLineCrossed()&CustomEvent(CTRENDLINE_CROSSED);
o zaman her satır kendi OnLineCrossed()'ını arayacaktır - bu sadece fiyatın o belirli satırdan geçip geçmediğini kontrol eden normal bir yöntem olmalıdır,
ve sonra CustomEvent(CTRENDLINE_CROSSED) çağırın - ki bu sadece ChartCustomEvent(..) olayını başlatmak için CTRENLINE_CROSSED olayını çağırmak içindir - yapınızda hangisi tekrar kapta işlenecek? Bu son kısım üçgen iletişimi yapan şey mi yoksa belki burada sadece iki farklı kavramı karıştırıyorum. Yani kapsayıcı, CTRENDLINE_CROSSED'i işleyen bir CustomEvent işleyicisine sahip olacak mı?

bazı şeylerin daha net hale geldiğini yazarak düşünüyorum (ve isterseniz CCar göz ardı edilebilir ve sadece trend çizgisine odaklanabilirsiniz) ama yine de GetPointer(this)'i neden her satıra taşıdığımı anlamıyorum? Ve örneğin ne tür bir olayda, konteyner fiyat değişikliklerini algılamak için her satırda özel olay alıcısını arayacak ve üçgen iletişim nerede veya sadece üçgen için sadece önceki örnekte mi uygulanıyor (CANyClass ile)?
Bu trend çizgisinde üçgen bir örnek uygulayabilir misiniz?

Zaman ayırdığınız, sabrınız ve şimdiye kadarki yardımlarınız için gerçekten teşekkür ederim, hiç belli değil. Olaya dayalı programlamanın potansiyeline gözlerimi açtığınızı söylemeliyim.