마운드에서 OOP에 대해 이야기하기 - 페이지 4

 
Dennis Kirichenko :

부분적 발언. 코드에서 인수가 지원되면 좋을 것입니다. 단지 그와 같은 것이 아니라 blah blah blah.

나는 지원한다.

다음은 내 CMyObject 클래스입니다.

 #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

마지막에 CONVERT_OBJECT_WITH_CHECK 매크로도 정의되며, 이는 DEBUG 버전의 경우 개체 유형에 따라 포인터 변환에 대한 추가 검사를 수행합니다.

 
George Merts :

나는 지원한다.

다음은 내 CMyObject 클래스입니다.

마지막에 CONVERT_OBJECT_WITH_CHECK 매크로도 정의되며, 이는 DEBUG 버전의 경우 개체 유형에 따라 포인터 변환에 대한 추가 검사를 수행합니다.


아름다운. 물론 취향의 문제입니다. 그러나 MQL 구문을 기반으로 다음과 같이 작성합니다.

 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 :

아름다운. 물론 취향의 문제입니다. 그러나 MQL 구문을 기반으로 다음과 같이 작성합니다.

네, 맞습니다.

그러나 이것은 내 구식 "프로그래밍 스타일"입니다(최근 스레드가 있는 Volchansky 안녕하세요).

나는 모든 열거를 가지고 있습니다 - E로 시작하고, 그 다음 "혹등한" 표기법(이름). 그리고 열거형의 유형 자체는 열거형 유형의 약어(최대 4자)로 시작합니다.

따라서 EMyObjectType 열거 이후 모든 값은 MOT_로 시작합니다.

 
Комбинатор :

당신은 바보예요? )) F#에 대해 나쁜 말을 한 마디도 하지 않았습니다. 당신의 어리석은 코멘트를 게시하기 전에 그들이 당신에게 쓰는 내용을 읽고 이해하는 법을 배우십시오.

OOP를 FP와 비교한다면 순수한 FP 언어와 비교하는 것이 합리적입니다. 하스켈. F#은 이미 그렇게 되어 있지만 파이썬과 R은 전혀 그렇지 않습니다. 그게 내가 의미한거야. 그렇지 않으면 C++도 FP에 속한다고 동의할 수 있습니다.

당신은 문맹 트롤입니다. 참고로 나열된 모든 언어는 어느 정도 기능이 있습니다. 가서 주제 영역을 가르치십시오. Andrei 가 어떤 좌표계에 있는지 이해하기 위해 질문을 했습니다. 아마도 그는 FP 언어 중 하나를 사용하므로 열거가 매우 일반적입니다.

 
George Merts :

아바스누이?

"기본 개체"에 무엇이 있어야합니까?

개인적으로 저는 모든 프로젝트에 거의 모든 개체가 있습니다. CMyObject 클래스에서 상속됩니다. public CObject, (내 개체에 두 개의 필드가 더 추가됨 - 클래스 이름과 인스턴스 ID), 반복적으로 CObject의 기능을 확인했습니다. ::Compare() - 매우 필요한 것으로 판명되었습니다. 몇 번 목록 포인터가 유용했습니다.

CObject에는 유형 제어를 제공하는 하나의 작업이 있습니다. 그리고 이것으로 그는 흔들리는 롤에 대처합니다. Next(), Prev() 등과 같은 메서드 이것은 매우 전문화된 컬렉션을 위한 것입니다. 그들은 CObject에 자리가 없습니다. Save 및 Load 메서드에도 동일하게 적용됩니다. 좋은 방법으로, 그리고 Comparer'가 그 안에 있어서는 안되지만 인터페이스가 없으면 이것이 유일한 솔루션입니다.

Type() 메서드는 강력한 타이핑을 제공하지 않기 때문에 일반 숫자를 반환합니다. 자신의 코드의 예를 통해 확인할 수 있습니다. 형식을 열거형으로 반환하는 새 GetType() 메서드를 정의합니다. 그리고 정말, 다른 방법이 없습니다. 제가 직접 합니다. 따라서 표준 CObject를 추가해야 하는 것으로 나타났으며 이는 잘못된 것입니다.

 

CObject::Compare() 에 대해 계속하겠습니다.

CFactoryBalanceResultSeries라는 개체가 있습니다. 이것은 전문가의 팩토리 개체에 대한 링크가 있는 균형 결과가 포함된 시리즈입니다. 사실, 이것은 그것을 거래한 전문가에 대한 참조와 함께 역사에 대한 균형 곡선입니다.

그래서 저는 이 동일한 밸런스 시리즈를 비교하는 스크립트를 가지고 있습니다.

시리즈가 두 개뿐이지만 비교하기 쉽습니다. 그러나 이미 눈으로 볼 때 수십 가지가있을 때 지옥을 비교할 수 있습니다.보다 공식적인 비교가 필요합니다.

그리고 이 과정을 자동화하기 위해 동일한 시리즈를 정렬하는 함수를 작성해야 했습니다. 여기에서 CFactoryBalanceResultSeries 클래스가 비교 기능이 있는 CObject의 상속자라는 사실이 유용했습니다. 우리는 이 함수를 재정의하고 시리즈를 정렬할 수 있는 기성품 기능을 가지고 있습니다.

내 기능은 다음과 같습니다.

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

즉, 정렬 유형에 따라 일반 정렬 기능에서 사용되는 원하는 비교 기능을 선택합니다.

예를 들어, 잔액 시리즈를 최대값에서 마지막 감소 부분으로 정렬하려는 경우 다음 함수가 사용됩니다.

 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()에 대해 계속하겠습니다.

신선한에서

CDouble & CDoubleVector
CDouble & CDoubleVector
  • 투표: 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, 별로 예쁘지 않습니다.

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

함수 포인터를 사용할 수 있습니다.

 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 :

네, 맞습니다.

그러나 이것은 내 구식 "프로그래밍 스타일"입니다(최근 스레드가 있는 Volchansky 안녕하세요).

나는 모든 열거를 가지고 있습니다 - E로 시작하고, 그 다음 "혹등한" 표기법(이름). 그리고 열거형의 유형 자체는 열거형 유형의 약어(최대 4자)로 시작합니다.

따라서 EMyObjectType 열거 이후 모든 값은 MOT_로 시작합니다.


예, 동일한 목록이 있습니다.

추신: 이제서야 컴퓨터에 도달했습니다. 예상대로 스레드는 빠르게 홍수에 빠졌습니다.)) 가상 기능 에 대한 이야기는 나중에 끝내도록 하겠습니다.. 이 포럼을 다음과 같이 불러야 합니다. chat-forum Bla-Bla-Bla ))

 

나는 모든 것을 읽었습니다. 모든 사람이 다른 관심을 가지고 있는 것입니다... 지금 가상 그리드를 설정하고 관리하기 위한 수업을 다시 하고 있습니다. 필요합니다.