OOP, mql5의 템플릿 및 매크로, 미묘함 및 사용 기술 - 페이지 14

 
Artyom Trishkin :

1. 그래도 이 "무언가"가 있는 것에 대해 즉시 이야기하고 중재자가 어떻게 할 것인지 생각하지 않는 것이 좋습니다. 그리고 나서 모든 것이 정말로 두 갈래로 흐려졌고, 이제 사회자가 토론이 있어야 한다고 결정하더라도 게시물의 순서와 의미를 유지하면서 토론 일정을 다시 잡는 것은 매우 시간 소모적인 작업입니다. .

2. 사회자의 행동에 대한 논의가 모든 재채기는 아닙니다 ... 이것은 그의 행동에 대한 일반 공개 경쟁이 시작되고 질서를 회복하거나 성난 사람들을 진정시키는 행동입니다. 그리고 자신의 의견이 있다면 누가 그것을 표현하는 것을 금지합니까? 어쩌면 당신의 의견은 매우 합리적인 제안이지만 모더레이터의 사랑받지 못하는 메뉴에 빠지지 않기 위해 말하기가 두려우신가요? 그래서 이것은 넌센스입니다 :)

명확하게 해 주셔서 감사합니다. 중요한 정보가 메인 스레드로 흘러들어가지 않도록 토론을 별도의 스레드로 유지하는 것이 가장 좋다고 생각했습니다. 게시물을 옮기기로 결정하시면 어디로 옮기실지 의논하겠습니다.

 
Ilya Malev :

귀하는 아직 어떤 분기가 더 적절한지 결정하는 중재자가 아닌 것 같습니다. 그리고 중재자는 기능에 대한 논의가 기능 자체의 스레드가 아니라 별도의 스레드, 즉 여기.

귀하의 설명에는 참조 및 유형 T의 값으로 클래스 메서드 에 균일하게 액세스하는 방법이 전혀 명확하지 않습니다. 무슨 말씀을 하시는지 모르겠지만 거기에 대해 이야기하고 있었습니다.

상황은 다음과 같습니다. 포럼 회원이 해당 스레드에서 볼 것으로 기대하는 기능에 모든 것을 맞출 수는 없다는 것을 깨달았습니다. 여기에서 논의가 진행 중입니다(여기서 진행 중이었습니다. 그래서 여기로 옮겼습니다). 이 주제를 별도의 스레드로 분리하기로 결정했습니다. 대부분의 기능에 대해 더 일반적이고 이해하기 쉬운 클래스가 있습니다. 여기에는 매크로(여전히 많은 사람들에게 수수께끼임)를 포함하여 해당 기능을 사용하기 위한 까다로운 트릭이 있습니다.

 
Ilya Malev :

명확하게 해 주셔서 감사합니다. 중요한 정보가 메인 스레드로 흘러들어가지 않도록 토론을 별도의 스레드로 유지하는 것이 가장 좋다고 생각했습니다. 게시물을 옮기기로 결정하시면 어디로 옮기실지 의논하겠습니다.

지금 그대로 두십시오. 가능하다면 논의된 예제를 해당 예제를 참조하는 게시물에 복사하세요(여기서 어떻게 시작했는지 이해하기 어렵습니다). 글쎄, 또는 더 이상 게시물을 편집할 수 없는 경우 개인 메시지에서 무엇을 삽입할지 알려주십시오.

 
Artyom Trishkin :

지금 그대로 두십시오. 가능하면 논의된 예제를 해당 예제를 참조하는 게시물에 복사하세요(여기서 어떻게 시작했는지 이해하기 어렵습니다). 글쎄, 또는 더 이상 게시물을 편집할 수 없는 경우 개인 메시지에서 무엇을 삽입할지 알려주십시오.

몇 가지 게시물 전에 이미 해당 스레드에서 코드를 복사했으므로 IMHO는 추가 단계가 필요하지 않습니다.

 
Ilya Malev :

몇 가지 게시물 전에 이미 해당 스레드에서 코드를 복사했으므로 IMHO는 추가 단계가 필요하지 않습니다.

좋은.

 

템플릿 및 정적을 통한 인터페이스 테마 업데이트. 더 정확하게는 인터페이스가 아니라 외부 클래스를 통해 구현되는 임의의 유형에 대해 편리하게 매개변수화된 작업이라고 가정해 보겠습니다. 이 경우 비교(Comparer) 및 유형 캐스팅 (Caster)

이전 비판을 부분적으로 고려했습니다. "인터페이스" 클래스(인터페이스는 아니지만)는 매개변수 클래스에서 상속되지 않습니다(이러한 메서드는 루트를 사용하지 않습니다...). 물론 dynamic_cast를 사용하지도 않습니다. 이 모델이 더 논리적으로 보이길 바랍니다.

#property strict

#define tnm typename
#define ttt template <tnm T>
#define ttf template <tnm F>
#define ttr template <tnm R>
#define tft template <tnm T,tnm F>
#define up(P) ( CheckPointer (P)!= POINTER_INVALID )

enum ECMP{ EQUAL= 0 , GREATER= 1 , LESSER=- 1 , UNDEF= INT_MAX };

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+

ttt class Type
 {
private :
  T item;
public :
  Type(){ ZeroMemory ( item ); }
  Type * operator = (T par){ item = par; return & this ; }
  T Get(){ return item; }
  
  ttf int operator != ( Type<F>&par )
   { 
       int r = Comparer< Type< T > *, Type< F > * >::Get().Compare( & this , &par );
      
       if ( r == UNDEF ) printf ( "Cannot compare %s to %s!" ,tnm(T),tnm(F));
       else {
         printf ( "%s (%s) to %s (%s) is %s" ,
          Caster<Type<T>*, string >::Get().Cast(& this ), tnm(T),
          Caster<Type<F>*, string >::Get().Cast(&par),  tnm(F), Caster<ECMP, string >::Get().Cast((ECMP)r)); }
       return r; 
   }
 };

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+

tft class Comparer
 {
private :
   static Comparer *handle;
public :
  Comparer(){ if ( handle == NULL ) handle = & this ; }
   static Comparer *Get(){ return handle ; }
   virtual ECMP Compare( T, F ){ return UNDEF; }
 };

//---

tft Comparer *Comparer::handle= NULL ;

tft class Caster
 {
private :
   static Caster *handle;
public :
  Caster(){ if ( handle == NULL ) handle = & this ; }
   static Caster *Get(){ return handle ; }
   virtual F Cast( T ){ F r; ZeroMemory (r); return r; }
 };

//---

tft Caster *Caster::handle= NULL ;

ttt class ToStrCaster: public Caster<T, string >
 {
public :
   virtual string Cast( T ){ return "N/A" ; }
 };

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+

class CmpIntToInt: public Comparer<Type< int >*,Type< int >*>
 {
public :
   virtual ECMP Compare( Type< int >* op1, Type< int >* op2 ){ return ECMP(up(op1)&&up(op2)?(op1.Get()>op2.Get())-(op1.Get()<op2.Get()):UNDEF); }
 }
citi;

class CmpDoubleToDouble: public Comparer<Type< double >*,Type< double >*>
 {
public :
   virtual ECMP Compare( Type< double >* op1, Type< double >* op2 ){ 
       return ECMP(up(op1)&&up(op2)? int (op1.Get()-op2.Get()> DBL_EPSILON )- int (op2.Get()-op1.Get()> DBL_EPSILON ):UNDEF); }
 }
cdtd;

class CmpStrToStr: public Comparer<Type< string >*,Type< string >*>
 {
public :
   virtual ECMP Compare( Type< string >* op1, Type< string >* op2 ){ 
       return ECMP(up(op1)&&up(op2)? StringCompare (op1.Get(),op2.Get()):UNDEF); }
 }
csts;

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+

class IntToStrCaster: public ToStrCaster<Type< int >*>
 {
public :
   virtual string Cast( Type< int >* par ){ return up(par)? IntegerToString (par.Get()): NULL ; }
 }
itsc;

class DoubleToStrCaster: public ToStrCaster<Type< double >*>
 {
public :
   virtual string Cast( Type< double >* par ){ return up(par)? DoubleToString (par.Get(), 6 ): NULL ; }
 }
dtsc;

class StringToStrCaster: public ToStrCaster<Type< string >*>
 {
public :
   virtual string Cast( Type< string >* par ){ return up(par)?par.Get(): NULL ; }
 }
stsc;

class ECMPToStrCaster: public ToStrCaster<ECMP>
 {
public :
   virtual string Cast( ECMP par ){ return EnumToString (par); }
 }
etsc;

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+

void OnStart ()
 {
  Type< int > t1= AccountNumber (), t2= AccountLeverage ();
  Type< double > t3= Ask , t4= Bid ;
  Type< string > t5= _Symbol ;
  
  t1!=t2;
  t4!=t3;
  t5!=t5;
  t1!=t3;
  t2!=t5;
 }


 

그러한 코드 조각에 대한 매크로를 작성하는 것이 얼마나 현실적입니까?

 input int    InDealType_01= 17 ;
input int    InDealType_02= 22 ;
.....
input double InVolume_01 = 0.1 ;
input double InVolume_02 = 0.3 ;
.....    
   EA.AddDealsSettings(InDealType_01,InVolType_01,InVolume_01,InPrice_01,InVolCoeff_01,InClosePips_01,Mirror);
   EA.AddDealsSettings(InDealType_02,InVolType_02,InVolume_02,InPrice_02,InVolCoeff_02,InClosePips_02,Mirror);
   EA.AddDealsSettings(InDealType_03,InVolType_03,InVolume_03,InPrice_03,InVolCoeff_03,InClosePips_03,Mirror);
   EA.AddDealsSettings(InDealType_04,InVolType_04,InVolume_04,InPrice_04,InVolCoeff_04,InClosePips_04,Mirror);
   EA.AddDealsSettings(InDealType_05,InVolType_05,InVolume_05,InPrice_05,InVolCoeff_05,InClosePips_05,Mirror);
   EA.AddDealsSettings(InDealType_06,InVolType_06,InVolume_06,InPrice_06,InVolCoeff_06,InClosePips_06,Mirror);
   EA.AddDealsSettings(InDealType_07,InVolType_07,InVolume_07,InPrice_07,InVolCoeff_07,InClosePips_07,Mirror);
   EA.AddDealsSettings(InDealType_08,InVolType_08,InVolume_08,InPrice_08,InVolCoeff_08,InClosePips_08,Mirror);
   EA.AddDealsSettings(InDealType_09,InVolType_09,InVolume_09,InPrice_09,InVolCoeff_09,InClosePips_09,Mirror);
   EA.AddDealsSettings(InDealType_10,InVolType_10,InVolume_10,InPrice_10,InVolCoeff_10,InClosePips_10,Mirror);

아직 입력변수( input )의 개수를 정하지 않았고, 선택영역 편집 지겹고, 한 줄에 대한 매크로는 문제가 되지 않지만, 10-15를 곱하는 방법을 모르겠습니다. 윤곽

 
Igor Makanu :

그러한 코드 조각에 대한 매크로를 작성하는 것이 얼마나 현실적입니까?

아직 입력변수(input)의 개수를 정하지 않았고, 선택영역 편집 지겹고, 한 줄에 대한 매크로는 문제가 되지 않지만, 10-15를 곱하는 방법을 모르겠습니다. 윤곽

나는 즉시 말합니다. 나는 µl을 확인하지 않았고, 확인하기 위해 sish 전처리기를 통해서만 실행했습니다. 결국 MKL에는 기능이 있으면 완료할 수 있습니다.

 #define ARGS HLP(InDealType_)    \
             HLP(InVolType_),    \
             HLP(InVolume_),     \
             HLP(InPrice_),      \
             HLP(InVolCoeff_),   \
             HLP(InClosePips_),  \
             Mirror
#define _CAT(L, R) L ##R
#define CAT(L, R) _CAT(L, R)
#define HLP(ARG)  CAT(ARG, INDEX)

#define INDEX 01
EA.AddDealsSettings(ARGS);
#undef INDEX
#define INDEX 02
EA.AddDealsSettings(ARGS);
#undef INDEX
#define INDEX 03
EA.AddDealsSettings(ARGS);
#undef INDEX

배기 가스를 얻었습니다(gcc -E):

EA.AddDealsSettings(InDealType_01 InVolType_01, InVolume_01, InPrice_01, InVolCoeff_01, InClosePips_01, Mirror);
EA.AddDealsSettings(InDealType_02 InVolType_02, InVolume_02, InPrice_02, InVolCoeff_02, InClosePips_02, Mirror);
EA.AddDealsSettings(InDealType_03 InVolType_03, InVolume_03, InPrice_03, InVolCoeff_03, InClosePips_03, Mirror);

args 목록에 추가 인수를 던집니다.

 
Igor Makanu :

그러한 코드 조각에 대한 매크로를 작성하는 것이 얼마나 현실적입니까?

아직 입력변수(input)의 개수를 정하지 않았고, 선택영역 편집 지겹고, 한 줄에 대한 매크로는 문제가 되지 않지만, 10-15를 곱하는 방법을 모르겠습니다. 윤곽

 #define TEST(dId) EA.AddDealsSettings(InDealType_ ##dId,InVolType_##dId,InVolume_##dId,InPrice_##dId,InVolCoeff_##dId,InClosePips_##dId,Mirror)
#define TEST2(d1,d2) do {TEST(d1);TEST(d2);} while ( false )
#define TEST3(d1,d2,d3) do {TEST2(d1,d2);TEST(d3);} while ( false )
#define TEST4(d1,d2,d3,d4) do {TEST2(d1,d2);TEST(d3,d4);} while ( false )
....
#define TEST100(d1,...d100) do {TEST50(d1,...d50);TEST50(d51,...d100);} while ( false )

void OnStart ()
  {
....
TEST4( 01 , 02 , 03 , 04 );
......
}

지금까지 나는 그것을 알아 냈습니다. 이제 개발자가 C에서와 같이 다양한 수의 매개변수를 조였다면 더 짧게 만드는 것이 가능했을 것입니다.

 
Vladimir Simakov :

지금까지 나는 그것을 알아 냈습니다. 이제 개발자가 C에서와 같이 다양한 수의 매개변수를 조였다면 더 짧게 만드는 것이 가능했을 것입니다.

내가 지나치게 복잡한 것)).

글쎄, 그가 첫 번째, 아마도 가장 최적의 것을 사용하게하십시오.

 #define TEST(dId)
TEST를 여러 번 작성하는 것은 결국 문제가 되지 않습니다.