Höyükte OOP hakkında konuşun - sayfa 4

 
Dennis Kirichenko :

Kısmi not. Argümanların kod tarafından desteklenmesi harika olurdu ve sadece böyle değil, falan filan.

Desteklerim.

İşte benim CMyObject sınıfım:

 #include <Object.mqh>

// Перечисление, в котором должны указываться все объекты, которые могут быть пронаследованны от моего объекта
enum EMyObjectTypes
{
   MOT_BASE_OBJECT                              =   0001 ,           // Просто CObject - фактически, никогда не должен использоваться.
   MOT_STRUCT_WRAPPER                           =   0002 ,           // Неинициализированный CStructWrapper
   MOT_PRICE_POINT                              =   0003 ,           // Класс CPricePoint   
   MOT_PRICEIDX_POINT                           =   0004 ,           // Класс CPriceIdxPoint  
   MOT_WPRICEIDX_POINT                          =   0005 ,           // Класс CWPriceIdxPoint  
   MOT_WAVE_TRIANGLE_DATA                       =   0006 ,           // Класс CWaveTriangleData
   MOT_WAVE_TRIANGLE                            =   0007 ,           // Класс CWaveTriangle
   MOT_TRADERESULT_I                            =   0008 ,           // Класс CTradeResultI
   MOT_TRADERESULT                              =   0009 ,           // Класс CTradeResult

   // Тут еще куча типов объектов - для каждого класса, свой ID
           
   MOT_UNKNOWN                                  = - 0001            // Неинициализированный объект.
};

/*

Класс СMyObject - потомок от СObject, несет функциональность именования.

*/

class CMyObject: public CObject
{
protected :
   EMyObjectTypes m_motType;
   int             m_iUDCreationValue;   // Значение, определяемое пользователем при создании объекта. Предназначено для идентификации отдельных экземпляров объекта.  
   
   
   void SetMyObjectType(EMyObjectTypes motType) { m_motType = motType; };  

   // Функции вывода на печать параметров. 
   void _PrintStringParameter( string strParameterName, string strParameterValue) { Print ( "Object ID: " + IntegerToString (GetType()) + "; " + strParameterName + " = " + strParameterValue + "; String." ); };
   void _PrintDoubleParameter( string strParameterName, double dParameterValue, int iDigits = 8 ) { Print ( "Object ID: " + IntegerToString (GetType()) + "; " + strParameterName + " = " + DoubleToString (dParameterValue,iDigits) + "; Double" ); };
   void _PrintIntegerParameter( string strParameterName, long lParameterValue) {   Print ( "Object ID: " + IntegerToString (GetType()) + "; " + strParameterName + " = " + IntegerToString (lParameterValue) + "; Integer" ); };
   void _PrintBoolParameter( string strParameterName, bool bParameterValue) { if (bParameterValue) Print ( "Object ID: " + IntegerToString (GetType()) + "; " + strParameterName + " = True; Bool" ); else Print ( "Object ID: " + IntegerToString (GetType()) + "; " + strParameterName + " = False; Bool" ); };
   
public :
   CMyObject( int iUDCreationValue = WRONG_VALUE ) { m_iUDCreationValue = iUDCreationValue;  m_motType = MOT_UNKNOWN;  };
   
   EMyObjectTypes GetType() const { return (m_motType);    };
   bool CheckType(EMyObjectTypes motType) { return (m_motType == motType); }; 
   
   int GetUDCreationValue() { return (m_iUDCreationValue); };
   void SetUDCreationValue( int iValue) { m_iUDCreationValue = iValue; };
};

#ifdef ASSERTION_CODE_ON

CMyObject* _PerformObjectConvertWithCheck(CMyObject* pmoObject,EMyObjectTypes motType)
{
   ASSERT_MYPOINTER(pmoObject);                     // проверим указатель
   ASSERT(pmoObject.CheckType(motType) == true );   // проверим внутренний ID типа объекта
   
   return (pmoObject);
};

#define CONVERT_OBJECT_WITH_CHECK(objFrom,typeTo,checkType) ((typeTo*)_PerformObjectConvertWithCheck(objFrom,checkType))

#else // ASSERTION_CODE_ON

#define CONVERT_OBJECT_WITH_CHECK(objFrom,typeTo,checkType) ((typeTo*)objFrom)

#endif // ASSERTION_CODE_ON

Sonunda, DEBUG sürümü için nesnenin türüne bağlı olarak ek bir işaretçi dönüşümü denetimi gerçekleştiren CONVERT_OBJECT_WITH_CHECK makrosu da tanımlanır.

 
George Merts :

Desteklerim.

İşte benim CMyObject sınıfım:

Sonunda, DEBUG sürümü için nesnenin türüne bağlı olarak ek bir işaretçi dönüşümü denetimi gerçekleştiren CONVERT_OBJECT_WITH_CHECK makrosu da tanımlanır.


Güzel. Tabii ki bu bir zevk meselesi. Ancak MQL sözdizimine dayanarak şöyle yazardım:

 enum ENUM_OBJECT_TYPES
{
   OBJECT_TYPES_BASE_OBJECT                              =   0001 ,           // Просто CObject - фактически, никогда не должен использоваться.
   OBJECT_TYPES_STRUCT_WRAPPER                           =   0002 ,           // Неинициализированный CStructWrapper
   OBJECT_TYPES_PRICE_POINT                              =   0003 ,           // Класс CPricePoint   
   OBJECT_TYPES_PRICEIDX_POINT                           =   0004 ,           // Класс CPriceIdxPoint  
   OBJECT_TYPES_WPRICEIDX_POINT                          =   0005 ,           // Класс CWPriceIdxPoint  
   OBJECT_TYPES_WAVE_TRIANGLE_DATA                       =   0006 ,           // Класс CWaveTriangleData
   OBJECT_TYPES_WAVE_TRIANGLE                            =   0007 ,           // Класс CWaveTriangle
   OBJECT_TYPES_TRADERESULT_I                            =   0008 ,           // Класс CTradeResultI
   OBJECT_TYPES_TRADERESULT                              =   0009 ,           // Класс CTradeResult

   // Тут еще куча типов объектов - для каждого класса, свой ID
           
   OBJECT_TYPES_UNKNOWN                                  = - 0001            // Неинициализированный объект.
};
 
Dennis Kirichenko :

Güzel. Tabii ki bu bir zevk meselesi. Ancak MQL sözdizimine dayanarak şöyle yazardım:

Evet bu doğru.

Ama bu benim eski moda "programlama tarzım" (son iş parçacığından merhaba Volchansky).

Tüm numaralandırmalara sahibim - E ile başlayın ve ardından "kambur" notasyonu - isim. Ve numaralandırmadaki türler, numaralandırma türünün bir kısaltmasıyla (dört harfe kadar) başlar.

Buna göre, EMyObjectType numaralandırmasından itibaren tüm değerler MOT_ ile başlar.

 
Комбинатор :

Sen bir salaksın? )) F# hakkında tek bir kötü söz söylemedim. Aptalca yorumlarınızı göndermeden önce size yazdıklarını okumayı ve anlamayı öğrenin.

OOP'yi FP ile karşılaştırırsak, saf bir FP dili ile karşılaştırmak mantıklıdır, yani. Haskell. F# zaten öyledir, ancak python ve R hiç değildir. Demek istediğim şey o. Aksi takdirde, C++'ın da FP'ye ait olduğu kabul edilebilir.

Okuma yazma bilmeyen bir trolsün. Referans olarak, listelenen tüm diller bir dereceye kadar işlevseldir. Git ve konu alanını öğret. Soru, Andrei'nin hangi koordinat sisteminde olduğunu anlamak için soruldu. Belki de FP dillerinden birini kullanıyor, bu yüzden numaralandırma çok geneldi.

 
George Merts :

Abasnuy?

"Temel nesne" de sizin üzerinizde ne olmalı?

Şahsen, tüm projelerde neredeyse TÜM nesnelerim var - CMyObject sınıfından miras alıyorlar: public CObject, (nesneme iki alan daha eklendi - sınıf adı ve örnek kimliği) ve tekrar tekrar CObject'in işlevselliğinin olduğundan emin oldum. ::Compare() - çok ihtiyaç duyulduğu ortaya çıktı. Liste işaretçileri birkaç kez işe yaradı.

CObject'in bir görevi vardır - tip kontrolü sağlamak. Ve bununla titrek rulolar başa çıkıyor. Next(), Prev(), vb. gibi yöntemler. bu çok özel koleksiyonlar içindir. CObject'te yerleri yoktur. Aynısı Kaydet ve Yükle yöntemleri için de geçerlidir. İyi bir şekilde, bunun içinde Comparer'a da yer verilmemeli, ancak arayüzler olmadan bu tek çözüm.

Type() yöntemine gelince, güçlü yazma sağlamaz çünkü normal bir sayı döndürür. Kendi kodlarınızın örneği ile doğrulayabilirsiniz. Türü bir numaralandırma olarak döndüren yeni bir GetType() yöntemi tanımlarsınız. Ve gerçekten, başka yolu yok, kendim yapıyorum. Bu nedenle, standart CObject'in eklenmesi gerektiği ortaya çıktı ve bu yanlış.

 

CObject::Compare() hakkında devam edeceğim.

Böyle bir nesnem var CFfactoryBalanceResultSeries - bu, uzmanın fabrika nesnesine bağlantı içeren denge sonuçlarına sahip bir seridir. Aslında, bu, ticareti yapan uzmana atıfta bulunularak, tarihin bir denge eğrisidir.

Bu aynı denge serilerini karşılaştırdığım bir senaryom var.

Sadece iki seri olmasına rağmen, bunları karşılaştırmak kolaydır. Ancak bir düzine olduğunda - zaten gözle - cehennemi karşılaştırabilirsiniz, daha resmi bir karşılaştırmaya ihtiyacınız var.

Ve sadece bu süreci otomatikleştirmek için, aynı serileri sıralayan bir fonksiyon yazmak gerekliydi. CFactoryBalanceResultSeries sınıfının, karşılaştırma işleviyle birlikte CObject'in mirasçısı olması benim için burada kullanışlı oldu. Bu işlevi yeniden tanımladık - ve dizileri sıralamak için hazır bir yeteneğimiz var.

İşlevim şöyle görünür:

 int CFactoryBalanceResultSeries::Compare( const CObject *poNode, const int iMode) const
{
   CFactoryBalanceResultSeries* pfdsAnother = CONVERT_OBJECT_WITH_CHECK(poNode,CFactoryBalanceResultSeries,MOT_FACTORYBALANCERES_SERIES);
   
   switch (iMode)
      {
       case FSM_BY_PART_OF_MAX_DD_A:     return (_CompareByPartOfMaxDDWith(pfdsAnother, true ));
       case FSM_BY_PART_OF_MAX_DD_D:     return (_CompareByPartOfMaxDDWith(pfdsAnother, false ));

       case FSM_BY_PART_OF_MAX_SLQUEUE_A: return (_CompareByPartOfMaxSLQueueWith(pfdsAnother, true ));
       case FSM_BY_PART_OF_MAX_SLQUEUE_D: return (_CompareByPartOfMaxSLQueueWith(pfdsAnother, false ));

       case FSM_BY_LAST_PRCDATA_A:       return (_CompareByLastPrcdataWith(pfdsAnother, true ));
       case FSM_BY_LAST_PRCDATA_D:       return (_CompareByLastPrcdataWith(pfdsAnother, false ));
       case FSM_BY_LAST_MNYDATA_A:       return (_CompareByLastMnydataWith(pfdsAnother, true ));
       case FSM_BY_LAST_MNYDATA_D:       return (_CompareByLastMnydataWith(pfdsAnother, false ));
       case FSM_BY_LAST_MNYLOTDATA_A:   return (_CompareByLastMnylotdataWith(pfdsAnother, true ));
       case FSM_BY_LAST_MNYLOTDATA_D:   return (_CompareByLastMnylotdataWith(pfdsAnother, false ));
      
       case FSM_BY_PRCYEARRECOVERY_A:   return (_CompareByYearPrcrecoveryWith(pfdsAnother, true ));
       case FSM_BY_PRCYEARRECOVERY_D:   return (_CompareByYearPrcrecoveryWith(pfdsAnother, false ));
       case FSM_BY_MNYYEARRECOVERY_A:   return (_CompareByMnyYearRecoveryWith(pfdsAnother, true ));
       case FSM_BY_MNYYEARRECOVERY_D:   return (_CompareByMnyYearRecoveryWith(pfdsAnother, false ));
       case FSM_BY_MNYLOTYEARRECOVERY_A: return (_CompareByMnylotYearRecoveryWith(pfdsAnother, true ));
       case FSM_BY_MNYLOTYEARRECOVERY_D: return (_CompareByMnylotYearRecoveryWith(pfdsAnother, false ));
      
       case FSM_BY_PRCVAR_A:             return (_CompareByPrcVarWith(pfdsAnother, true ));
       case FSM_BY_PRCVAR_D:             return (_CompareByPrcVarWith(pfdsAnother, false ));
       case FSM_BY_MNYVAR_A:             return (_CompareByMnyVarWith(pfdsAnother, true ));
       case FSM_BY_MNYVAR_D:             return (_CompareByMnyVarWith(pfdsAnother, false ));
       case FSM_BY_MNYLOTVAR_A:         return (_CompareByMnylotVarWith(pfdsAnother, true ));
       case FSM_BY_MNYLOTVAR_D:         return (_CompareByMnylotVarWith(pfdsAnother, false ));
      
       case FSM_BY_PRC_GRAILRATIO_A:     return (_CompareByPrcGrailratioWith(pfdsAnother, true ));
       case FSM_BY_PRC_GRAILRATIO_D:     return (_CompareByPrcGrailratioWith(pfdsAnother, false ));

       case FSM_BY_MAGIC_A:             return (_CompareByMagicWith(pfdsAnother, true ));
       case FSM_BY_MAIGC_D:             return (_CompareByMagicWith(pfdsAnother, false ));
       default :
         break ;
      };
         
   return ( NULL );
};

Yani, sıralama türüne bağlı olarak, genel sıralama işlevinde kullanılan istenen karşılaştırma işlevini seçiyoruz.

Örneğin, bakiye serisini maksimumdan son düşüşün kısmına göre sıralamak istersek, aşağıdaki fonksiyonlar kullanılacaktır:

 int CFactoryBalanceResultSeries::_CompareDblData( double dDataFirst, double dDataSecond, bool bAccending) const
{
   if (dDataFirst > dDataSecond)
      {
       if (bAccending)
         return ( 1 );
       else    
         return (- 1 );
      };
   
   if (dDataFirst < dDataSecond)
      {
       if (bAccending)
         return (- 1 );
       else    
         return ( 1 );
      };
      
   return ( NULL );         
};

int CFactoryBalanceResultSeries::_CompareByPartOfMaxDDWith(CFactoryBalanceResultSeries* pfdsAnother, bool bAccending) const
{
   if (Total()== 0 || pfdsAnother.Total() == 0 || m_pepfFactory.GetControlParams().m_dMaxPriceDrawdown == 0 )
       return ( NULL );
   
   double dLocalPart = GetCurPriceDD() / m_pepfFactory.GetControlParams().m_dMaxPriceDrawdown;
   double dRemotePart = pfdsAnother.GetCurPriceDD() / pfdsAnother.GetFactory().GetControlParams().m_dMaxPriceDrawdown;
      
   return (_CompareDblData(dLocalPart,dRemotePart,bAccending));   
};
 
George Merts :

CObject::Compare() hakkında devam edeceğim.

taze

CDouble & CDoubleVector
CDouble & CDoubleVector
  • oylar: 4
  • 2018.01.09
  • nicholishen
  • www.mql5.com
A library for common rounding methods used in MQL development, primitive wrapper class for type (double), and vector for CDouble objects. MQL5 and MQL4 compatible! CDouble The CDouble class wraps a value of the primitive type double in an object. Additionally, this class provides several methods and static methods for rounding doubles and...
 
George Merts :



IMHO, çok güzel değil.

 int CFactoryBalanceResultSeries::Compare( const CObject *poNode, const int iMode) const
{
   CFactoryBalanceResultSeries* pfdsAnother = CONVERT_OBJECT_WITH_CHECK(poNode,CFactoryBalanceResultSeries,MOT_FACTORYBALANCERES_SERIES);
   
   switch (iMode)
      {
       case FSM_BY_PART_OF_MAX_DD_A:     return (_CompareByPartOfMaxDDWith(pfdsAnother, true ));
       case FSM_BY_PART_OF_MAX_DD_D:     return (_CompareByPartOfMaxDDWith(pfdsAnother, false ));

       case FSM_BY_PART_OF_MAX_SLQUEUE_A: return (_CompareByPartOfMaxSLQueueWith(pfdsAnother, true ));
       case FSM_BY_PART_OF_MAX_SLQUEUE_D: return (_CompareByPartOfMaxSLQueueWith(pfdsAnother, false ));

Bir işlev işaretçisi kullanabilirsiniz .

 typedef int (*TCompare1)( int , bool ); 
// ---
int CFactoryBalanceResultSeries::Compare( const CObject *poNode, const int iMode) const
{
   CFactoryBalanceResultSeries* pfdsAnother = CONVERT_OBJECT_WITH_CHECK(poNode,CFactoryBalanceResultSeries,MOT_FACTORYBALANCERES_SERIES);
   
   switch (iMode)
      {
       case FSM_BY_PART_OF_MAX_DD_A:     return (TCompare1(pfdsAnother, true ));
       case FSM_BY_PART_OF_MAX_DD_D:     return (TCompare1(pfdsAnother, false ));

       case FSM_BY_PART_OF_MAX_SLQUEUE_A: return (TCompare1(pfdsAnother, true ));
       case FSM_BY_PART_OF_MAX_SLQUEUE_D: return (TCompare1(pfdsAnother, false ));

.....
      }
}
 
George Merts :

Evet bu doğru.

Ama bu benim eski moda "programlama tarzım" (son iş parçacığından merhaba Volchansky).

Tüm numaralandırmalara sahibim - E ile başlayın ve ardından "kambur" notasyonu - isim. Ve numaralandırmadaki türler, numaralandırma türünün bir kısaltmasıyla (dört harfe kadar) başlar.

Buna göre, EMyObjectType numaralandırmasından itibaren tüm değerler MOT_ ile başlar.


Evet, aynı listelere sahibim.

Not: Ancak şimdi bilgisayara geçtim. Beklendiği gibi, iş parçacığı hızla bir sele dönüştü)) Sanal işlevlerle ilgili hikayeyi daha sonra bitirmeye çalışacağım .. Bu forumu şöyle adlandırmalıyız: sohbet-forumu Bla-Bla-Bla ))

 

Her şeyi okudum, herkesin farklı ilgi alanları var ... Şimdi sanal bir grid kurmak ve yönetmek için bir sınıf yeniden yapıyorum, buna ihtiyacım var.

Neden: