객체를 동적으로 생성하는 방법은 무엇입니까? (일부 OOP 물건) - 페이지 2

 
Doerk Hilger :

나는 당신이 그것을 완전히 잘못하고 있다고 말하고 싶지 않지만 이것은 OOP가 아닌 구조체 프로그래밍이기 때문에 그렇게합니다. 가장 큰 차이점은 상속과 오버로딩의 힘입니다. 그건 그렇고, 실제 그래픽 개체에서 실제로 상속할 수는 없지만 코드 개체로 무엇이든 나타낼 수 있고 이 개체에서 선이나 무엇이든 참조할 수 있습니다. 그것이 MFC 또는 MQL 클래스인지 여부에 관계없이 모든 클래스에서 일반적으로 수행되는 방식입니다.

선이 객체라면 그와 같이 취급하십시오. 외부 배열을 처리하지 말고 클래스 컬렉션 내부에서 처리하고 포인터로 작업하십시오. CWndContainer를 살펴보고 아이디어를 얻으십시오. 이 클래스는 주로 CWnd 개체에 대한 포인터 배열을 관리하는 컨테이너입니다. 한 단계 더 나아가 귀하의 구조는 다음과 같아야 합니다.

모든 개체의 기반이 되는 CObject

선과 같은 모든 가격/시간 기반 개체에 대한 기본이 되는 CPriceTimeObjects는 CObject에서 파생됩니다. 생성을 제어하고 시간과 가격을 유지하며 다음 상속자가 사용할 수 있는 OnCreate()를 호출합니다. 또한 상속자에 의해 오버로드되는 가상 OnTick()을 호출하는 Tick 함수도 있습니다.

추세선의 기준으로 CTrendLine은 CPriceTimeObjects에서 상속하고 ObjectCreate 함수 를 사용하여 최종 라인을 생성하는 OnCreate를 처리합니다. 또한 Tick 이벤트에 반응/응답하는 OnTick() 처리기가 있어야 합니다. 내가 이해하는 한 가격에 민감해야 하기 때문입니다.

이 외에도 원하는 모든 CTimePriceObject 개체를 보유하는 포인터 배열을 관리하는 컨테이너 클래스가 있습니다. 이 클래스는 CTimePriceObject에서도 자신을 상속하고 OnTick()을 "자식"에 전달합니다. 컨테이너에는 OnChartEvent()를 처리하여 줄을 추가하거나 제거하는 기능도 있습니다. 또한 케이스에 대한 모든 기존 개체를 스캔하는 스캔 기능이 있어야 하며 라인이 생성된 후 전문가가 추가되었습니다. 또한 CTimePrice에서 오버로드된 OnTick()을 처리하고, 거기에서 배열을 반복하고, 가상 OnTick에 의해 처리되는 모든 자식 개체의 Tick 함수를 호출하여 반응해야 하는 책임이 있는지 여부를 모든 CTrendLine 개체에 묻습니다. 이건 또 왜? CTrendLine은 CTimePrice에서도 이 함수를 오버로드하기 때문에 이 클래스는 추가 기능이 있는 추가 상속자도 상속할 수 있습니다.

아주 좋아, 도렉.

하지만 몇 가지 질문이 있습니다.

CTimePriceObject를 보유하는 컨테이너가 CTimePriceObject에서 자신을 상속해야 하는 이유는 무엇입니까? 예를 들어, 표준 라이브러리의 CIndicators는 CArrayObj에서 상속하며 대부분 상속 없이 CIndicator를 참조합니다.
나는 그것이 일반 배열이 아닌 표준 lib를 사용하기를 원한다는 것을 알고 있지만, 특정 종류의 객체의 컨테이너가 객체 자체를 상속해야 한다는 개념에 대한 무언가가 나에게 불분명합니다(컨테이너 자체가 포함하는 객체가 아니기 때문에, 즉, "is" 관계가 없음) 그것이 옳다고 느끼더라도.
그것에 대한 당신의 견해를 명확히 해주실 수 있습니까?

둘째, CTrendLine이 언어 네이티브 ObjectCreate 함수를 사용하여 최종 라인을 생성한다고 말할 때 표준 라이브러리에 의존하지 않고 처음부터 프레임워크를 구축하는 것처럼 보입니다.
예를 들어 표준 라이브러리 자체를 확장하는 것이 좋습니다. 표준 라이브러리의 모든 CIndicator 개체가 가격이 버퍼에 몇 번이나 닿았는지 말할 수 있기를 원한다고 가정합니다.
마지막 X 막대에서. CIndicator 또는 CIndicatorBuffer와 같은 기본 클래스를 확장하면 표준 라이브러리에서 상속받아야 하는 표준 라이브러리의 모든 종속 개체가 있기 때문에 이 작업을 어떻게 수행하시겠습니까?
예를 들어 CiMA와 같은 새 CIndicator 또는 새 CBuffer. 모든 사용자 지정 표시기 클래스를 폴더에 복사하고 상속을 새 CIndicatorBuffer로 변경하시겠습니까? 그러면 메타따옴표가 표준 CIndicatorBuffer 또는 상위 클래스에 무언가를 추가하면 어떻게 될까요?

통찰력을 주셔서 대단히 감사합니다.

BR

 

Willbur :

...

이 방법으로 이동하면 내 SmartLine 개체가 추세선, 화살표, 텍스트 개체 및 이 모든 항목 옆에 있는 MT5 메뉴에 나타나야 합니다.

...

MT5가 이를 허용하는 경우에만 가격이 변경될 때 터미널 프로그램이 개체를 트리거할 수 있는 방법에 대한 나머지 질문에 대해 논의해야 합니다.

...
mql5에서는 그렇게 할 수 없습니다.
 
Amir Yacoby :

아주 좋아, 도렉.

하지만 몇 가지 질문이 있습니다.

CTimePriceObject를 보유하는 컨테이너가 CTimePriceObject에서 자신을 상속해야 하는 이유는 무엇입니까? 예를 들어, 표준 라이브러리의 CIndicator는 CArrayObj에서 상속되며 대부분 상속 없이 CIndicator를 참조합니다.
나는 그것이 일반 배열이 아닌 표준 lib를 사용하기를 원한다는 것을 알고 있지만, 특정 종류의 객체의 컨테이너가 객체 자체를 상속해야 한다는 개념에 대한 무언가가 나에게 불분명합니다(컨테이너 자체가 포함하는 객체가 아니기 때문에, 즉, "is" 관계가 없음) 그것이 옳다고 느끼더라도.
그것에 대한 당신의 견해를 명확히 해주실 수 있습니까?

둘째, CTrendLine이 언어 네이티브 ObjectCreate 함수를 사용하여 최종 라인을 생성한다고 말할 때 표준 라이브러리에 의존하지 않고 처음부터 프레임워크를 구축하는 것처럼 보입니다.
예를 들어 표준 라이브러리 자체를 확장하는 것이 좋습니다. 표준 라이브러리의 모든 CIndicator 개체가 가격이 버퍼에 몇 번이나 닿았는지 말할 수 있기를 원한다고 가정합니다.
마지막 X 막대에서. CIndicator 또는 CIndicatorBuffer와 같은 기본 클래스를 확장하면 표준 라이브러리에서 상속받아야 하는 표준 라이브러리의 모든 종속 개체가 있기 때문에 이 작업을 어떻게 수행하시겠습니까?
예를 들어 CiMA와 같은 새 CIndicator 또는 새 CBuffer. 모든 사용자 지정 표시기 클래스를 폴더에 복사하고 상속을 새 CIndicatorBuffer로 변경하시겠습니까? 그러면 메타따옴표가 표준 CIndicatorBuffer 또는 상위 클래스에 무언가를 추가하면 어떻게 될까요?

통찰력을 주셔서 대단히 감사합니다.

BR

1. 컨테이너의 상속.

MQL의 한계는 다중 상속을 가질 수 없다는 것입니다. 그렇기 때문에 적어도 한 번은 죽어야 합니다. 물론 당신이 옳습니다. CArrayObj에서 상속하는 것도 의미가 있지만 컨테이너가 Tick()->OnTick()과 같이 CTimePrice 개체가 처리하는 모든 이벤트를 처리하고 배포하기 때문에 그렇게 하지 않습니다. 배열 객체는 그것과 아무 관련이 없습니다. 동일한 기본 클래스에서 상속되는 다른 개체를 보유하는 컨테이너 개체는 단순히 더 많은 공통점을 가지고 있습니다. 그러한 컨테이너는 또한 가격과 시간에 따라 앵커를 가질 수 있으며, 그러한 컨테이너를 이동/이동할 때 모든 "자식"도 이동하는 것이 컨테이너의 작업이 될 것입니다. 이것은 단지 예일 뿐이지만 그러한 아이디어의 목록은 아마도 배열 기능에 대한 아이디어의 목록보다 더 길 것입니다.

그리고 네, 그렇습니다. 많은 유형의 객체를 처리하는 클래스를 실제로 만들었습니다. 그동안의 경험에 따르면 이러한 방식으로 상속을 관리하는 것이 올바른 결정이었다는 것을 알 수 있습니다.

2. 처음부터 프레임워크.

여기 비슷합니다. 표준 라이브러리에 대해 조금 더 깊이 들어가기 시작했을 때 나는 마음에 들지 않는 많은 것들을 발견했습니다. 그것들의 나쁜 성능뿐만 아니라 유연성 부족과 불완전한 아키텍처 때문입니다. 예를 들어 전역 CMouse 클래스/개체와 CWnd와 CObject 사이의 클래스가 누락되었습니다. CWnd 개체는 차트와 선의 자식이고 그러한 개체에 대한 연결이 없고 그러한 개체의 최종 구현이 없기 때문입니다. 내가 위에서 설명한 것처럼 전혀. 그리고 하나의 명령으로 모든 차트 개체를 표시/숨길 수 있는 모든 차트 개체를 보유하고 있는 마스터 개체가 없습니다. CCanvas, 같은 것, 좋은 클래스이지만 CWnd에서 상속된 비트맵을 기반으로 대화형 개체를 만들 수 있는 CWnd를 사용한 구현은 어디에 있습니까? 등등.

게다가, 모든 표준 라이브러리의 전체 구조는 사이드 체인을 허용하지 않지만 MQL은 void 포인터를 허용하지 않기 때문에 이것은 필요합니다. 예를 들면: 끌 수 있는 추세선 개체를 만들 수 있는 CDragLine이라는 클래스를 사용하고 있습니다. 이러한 추세선 개체가 주문에 연결되고 더 나아가 패널/디스플레이에 연결되는 경우 연결된 패널이 주문 변경으로 인해 발생하는 이동/변경에 대한 정보도 가져오는 사이드 체인을 사용할 가능성이 필요합니다. . 그리고 그 반대의 경우에도 주문을 이동하고 선 자체가 드래그될 때 패널에 알리는 옵션이 필요합니다. 이러한 종류의 삼각형 메시징은 표준 라이브러리 로 수행할 수 없습니다. 이것은 사이드 체인에 의해 수행됩니다. 즉, 절대적으로 모든 개체는 고급 버전의 CObject에서 상속됩니다. 이 클래스는 다른 개체를 개체에 연결할 수 있고 연결된 개체에 메시지를 보낼 수 있습니다. 이렇게 하면 이상한 코드 없이 훨씬 더 복잡하고 효과적인 메시징이 가능합니다.

모든 사람이 무엇을 해야 하는지에 대한 권장 사항을 제공할 수는 없지만 실제로 표준 라이브러리의 99%를 삭제하기로 결정했습니다. 원본에서 남겨둔 유일한 클래스는 CCanvas입니다(그러나 일부 변경 사항 및 버그 수정이 있는 경우 Code Base 참조 ) 및 CSymbolInfo.

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

누군가가 사이드 체인 기능에 관심이 있다면 여기 내 CObject 클래스의 코드가 있습니다. 업데이트할 때마다 Object.mqh에서 원본 CObject를 교체하면 표준 라이브러리의 대부분이 이 사이드 체인 기능의 향상을 얻습니다. 그건 그렇고, 노드 연결도 구현됩니다. 이는 원본에서 수행되지 않습니다.

이러한 사이드 체인 기능을 추가하려면 수신 클래스 내에서 다음과 같이 하십시오.

 //--- 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))
               {
               //...
               } 
         }            
   };

보내는 클래스 CWhatEver 및 CFurther는 수신기가 있는지 없는지와 같은 수신기에 대해 아무것도 모릅니다. 코드는 다음과 같습니다.

 //---
//...

   CustomEvent( 123456 );

//...
//---

다음은 CObject 대체입니다.

 //+------------------------------------------------------------------+
//|                                                       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
 

사이드 체인 아이디어를 자세히 설명하고 공유해 주셔서 감사합니다.

솔직히, 나는 잘 이해하지 못하고 코드가 컴파일되지 않습니다 (나는 아이디어를 얻기 위해 생성자로 게시 한 CObject를 직접 상속하는 빈 클래스로 CWhatEver 및 CFurther를 만들었습니다).

2 CWhatEver::CWhatEver에 대해 수신된 컴파일 오류는 개인 멤버 함수 를 호출할 수 없으며 CFurther에 대한 동일한 오류입니다.

어쨌든 "사이드 체인"이라는 용어를 Google에 검색했지만 찾을 수 없었습니다. 당신이 어떤 서면 자료를 알게 된다면 내가 그것을 읽을 수 있을 것입니다.

BR

 

예, 클래스가 비어 있기 때문에 컴파일되지 않습니다. 이들은 단지 자리 표시자입니다.

사이드 체인은 공식적인 설명이 아닐 수 있습니다. 오히려 무효 포인터 및/또는 다중 상속에 대한 깔끔한 MQL 해결 방법입니다. 간단히 말해서: 모든 클래스 간에 통신할 수 있는 기능을 제공하고 개체가 클래스에 포함된 경우 매우 유용합니다. 포함하는 클래스가 사용자 정의 이벤트 의 수신자임을 "말할" 수 있기 때문입니다. 이렇게 하면 스파게티 코딩을 피할 수 있습니다.

예를 들어 다음과 같은 것이 있는 경우

반환 OnClick();

마지막 파생 클래스의 오버로드를 먼저 호출하면 다음과 같이 확장할 수 있습니다.

반환 OnClick()&CustomEvent(CUSTOM_CLICK);

이렇게 하면 일반적으로 다음을 갖는 파생 클래스뿐만 아니라

가상 부울 OnClick()

함수에 알림이 표시되고 개체를 포함하는 클래스도 클릭 알림을 받을 수 있습니다.

 

메시지를 보내는 다른 개체를 알아야 하는 일반적인 메시징이 아니라 사용자 지정 이벤트 를 통해 두 개체 간에 통신하는 방법을 의미합니까?

그런 생각이 들었습니다. 하지만 포함된 개체는 무엇을 의미합니까? CAnyClass 코드에는 두 개의 개인 객체가 있습니다. 내장이라는 것은 그들의 몸도 내부에 데칼링되어야 한다는 것을 의미합니까?
CAnyClass 또는 외부에서 정의할 수 있습니까? 내 말은, 용어를 사용할 때 포함된 것이 다른 개체 내부에 비공개인 개체입니까?

예를 들어 내가 CAnyClass 외부에 CWhatEver를 작성하고 이벤트에 대해 CAnyClass에 메시지를 보내고 싶다면 CWhatEver에서 내가 반환한다는 의미입니까?

반환 OnClick()&CustomEvent(CUSTOM_CLICK); // <=== & 대신 &&를 의미합니까 ????

평소와 같이 CWhatEver의 파생 클래스와 CAnyClass(사용자 지정 이벤트로 인해)를 포함하는 클래스에 메시지를 보내는 것은 무엇입니까?

그리고 왜 CObject가 #ifndef 안에 정의되어 있습니까?

BTW, CObject에서 stdlib.mqh의 목적은 무엇입니까?

 

아래에서 위로...

- stdlib, 어쨌든 원래 object.mqh에 포함되어 있지 않습니까? 여기에는 필요하지 않지만 두 개의 두 배를 비교할 수 있는 유일한 신뢰할 수 있는 방법인 CompareDouble()이 포함되어 있습니다.

- 표준 및 조건부 컴파일에 대한 이중 정의를 피하기 위해 #ifndef를 사용합니다.

- 예, 삼각 메시징의 경우

- 이진 & 및 논리 버전 &&는 bool 결과와 동일합니다.

- 임베디드란 외래 클래스의 인스턴스/객체가 다른 클래스의 일부이고 둘 다 서로 파생되지 않는 경우를 의미합니다. OnClick() 예제를 사용하고 m_object가 내부 목적을 위해 어떻게든 OnClick()을 처리한다고 가정합니다(예: 버튼인지 여부). 이 사용자 정의 이벤트 없이 클릭이 있었다는 것을 CAnyClass 내에서 알아야 하는 경우 코드는 어떻게 생겼습니까?

솔직히 매일매일 필요로 하는 기능은 아니지만 방향성 뿐만 아니라 소통이 필요한 상황이라면 솔루션입니다.

원래 스레드 문제로 돌아가십시오. 아이디어는 어레이를 사용하여 가격에 반응하는 여러 라인을 관리하는 것이었습니다. 이 선 개체는 선이 촛불에 의해 교차되고 일부 동작을 강제할 때 이벤트를 처리합니다. 용기를 사용하는 것이 좋습니다. 예를 들어 이 컨테이너가 이제 이러한 작업을 계산하려는 경우 컨테이너가 예를 들어

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

물론 CTrendLine 클래스는 다음과 같이 구현해야 합니다.

반환 OnLineCrossed()&CustomEvent(CTRENDLINE_CROSSED);

 
와우 , 포럼에 그런 토론있다는 것이 얼마나 좋은지 . 비록 내가 아직 OOP 시작 단계에 있다는 것을 인정 해야 하지만 .

불행히도 나는 2주 동안 휴가 갑니다 . P 레인은 몇 시간 후에 출발합니다( 좋아요 , 더 나쁠 수 있음 ) .

이 시점에서 이미 한 가지 질문 이 있습니다 . MQL 프레임 작업 에 대한 자세한 문서 어딘가에 있습니까?


윌버
 
Willbur :
..

이 시점에서 이미 한 가지 질문 이 있습니다 . MQL 프레임 작업 에 대한 자세한 문서 어딘가에 있습니까?

아니요 :-(

내 경험에 따르면 "mql 프레임워크"를 공부하는 법을 배우는 것이 좋습니다. 그러나 Doerk가 말했듯이 Standard Library 에는 많은 문제가 있으며 제 생각에는 심각하고 큰 프로젝트에서는 사용할 수 없습니다.

 
Doerk Hilger :

아래에서 위로...

- stdlib, 어쨌든 원래 object.mqh에 포함되어 있지 않습니까? 여기에는 필요하지 않지만 두 개의 두 배를 비교할 수 있는 유일한 신뢰할 수 있는 방법인 CompareDouble()이 포함되어 있습니다.

- 표준 및 조건부 컴파일에 대한 이중 정의를 피하기 위해 #ifndef를 사용합니다.

- 예, 삼각 메시징의 경우

- 이진 & 및 논리 버전 &&는 bool 결과와 동일합니다.

- 임베디드란 외래 클래스의 인스턴스/객체가 다른 클래스의 일부이고 둘 다 서로 파생되지 않는 경우를 의미합니다. OnClick() 예제를 사용하고 m_object가 내부 목적을 위해 어떻게든 OnClick()을 처리한다고 가정합니다(예: 버튼인지 여부). 이 사용자 정의 이벤트 없이 클릭이 있었다는 것을 CAnyClass 내에서 알아야 하는 경우 코드는 어떻게 생겼습니까?

솔직히 매일매일 필요로 하는 기능은 아니지만 방향성 뿐만 아니라 소통이 필요한 상황이라면 솔루션입니다.

원래 스레드 문제로 돌아가십시오. 아이디어는 어레이를 사용하여 가격에 반응하는 여러 라인을 관리하는 것이었습니다. 이러한 선 개체는 선이 촛불에 의해 교차되고 일부 동작을 강제할 때 이벤트를 처리합니다. 용기를 사용하는 것이 좋습니다. 예를 들어 이 컨테이너가 이제 이러한 작업을 계산하려는 경우 컨테이너가 예를 들어

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

물론 CTrendLine 클래스는 다음과 같이 어떻게든 구현해야 합니다.

반환 OnLineCrossed()&CustomEvent(CTRENDLINE_CROSSED);

stdlib 나는 단지 MQL4라고 생각했지만 어쩌면 내가 틀릴 수도 있습니다.
죄송합니다. 전체 CObject가 #ifndef 안에 있어야 하는 이유를 이해하지 못했습니다. 평이하게 쓰여진다면 무엇을 이중으로 정의할 것인가? 그리고 btw, 왜 CStruct를 CObject 위에 빈 클래스로 두나요?

임베디드 클래스에 대해 (저도 25년 동안 프로그래머지만 OO는 아닙니다) 귀하의 예제는 예를 들어 이와 같은 상황을 언급합니까? 내가 CCar 클래스이고 CWheel 클래스를 포함했다고 가정합니다.
그리고 CWheel에는 최소 공기압에 대한 이벤트 핸들러가 있습니다. 그리고 나는 자동차로서 그것을 알아야 합니까?
이 예제 또는 다른 특정 항목과의 유사점을 찾을 수 있다면 어떤 클래스에서 이벤트를 발생시키는지(클릭으로 제공한 예제에서는 분명히 차트임) 누가 처리하는지에 대해서는 아직 확신이 서지 않기 때문입니다. 그리고 기술적으로도 예를 들어 다음 라인을 이해합니다(그 목적은 컨테이너가 가격을 가로지르는 추세선을 관리하는 작업을 막대로 관리하는 방법을 보여주는 것이라고 가정합니다).

m_trendline[n].CustomEventReceiver(PTR(this));
내가 제대로 이해했는지 명확히 할 수 있습니까? 루프에서 모든 추세선 [1..n]을 호출합니까? 그렇다면 컨테이너가 현재 처리하고 있는 일반 이벤트의 유형은 무엇입니까? 선이 아니다
모든 라인을 호출하기 때문에 특정 이벤트. CTRENDLINE_CROSSED 이벤트를 유발할 가능성이 있는 새로운 바 또는 가격 변경과 같을 수 있습니까? 그리고 왜 GetPointer(this)를 각 라인에 보내나요?
라인은 컨테이너를 콜백해야 하며 그 이유는 무엇입니까?
그렇다면,

반환 OnLineCrossed()&CustomEvent(CTRENDLINE_CROSSED);
그런 다음 각 줄은 자체 OnLineCrossed()를 호출합니다. 이는 가격이 해당 특정 줄을 초과했는지 확인하는 일반 메서드여야 합니다.
그런 다음 CustomEvent(CTRENDLINE_CROSSED)를 호출합니다. 이 호출은 ChartCustomEvent(..)를 호출하여 이벤트 CTRENLINE_CROSSED를 발생시키는 것입니다. 구조에서 컨테이너에서 다시 처리될 이벤트는 무엇입니까? 삼각 의사 소통을 만드는 마지막 부분입니다. 아니면 여기에서 두 가지 다른 개념을 혼합하고 있습니다. 따라서 컨테이너에는 CTRENDLINE_CROSSED를 처리하는 CustomEvent 핸들러가 있습니까?

몇 가지 사항이 더 명확해 졌다고 생각하는 경우 (원하는 경우 CCar를 무시하고 추세선에만 집중할 수 있음) 여전히 GetPointer(this)를 각 줄로 옮기는 이유를 모르겠습니다. 그리고 예를 들어 어떤 종류의 이벤트에서 컨테이너가 가격 변동을 감지하기 위해 각 라인에서 사용자 지정 이벤트 수신기를 호출하고 삼각 통신은 어디에 있습니까?
이 추세선에 삼각형의 예를 적용할 수 있습니까?

지금까지 시간과 인내심과 도움에 진심으로 감사드립니다. 전혀 명확하지 않습니다. 이벤트 중심 프로그래밍의 가능성에 눈을 뜨셨다고 말씀드리고 싶습니다.

사유: