mql5中的OOP、模板和宏,细微之处和用途 - 页 14

 
Artyom Trishkin:

1.最好是在事情发生的地方谈论它,而不是想着主持人会怎么做。否则,一切都会变得模糊不清,变成两条线,现在,即使版主决定讨论应该在那里或那里,在保持帖子的顺序和它们的意义的情况下,正常移动讨论是一项相当费力的工作。

2)讨论版主的行为并不是每一个喷嚏...这不是每一个喷嚏,但如果你想公开挑战他,无论是为了恢复秩序还是平息狂热。如果你有意见,谁禁止你表达?也许你的意见是一个非常理性的建议,但你不敢说出来,以免落入版主不爱的菜单?所以那是胡说八道 :)

谢谢你的澄清。我认为最好在一个单独的主题中进行讨论,这样就不会使主线中的所谓有价值的信息变得混乱。如果你决定移动帖子,我将讨论你把它们移到哪里。

 
Ilya Malev:

你还不是版主,要确定在哪个主题中什么更合适。而且版主已经明确表示,关于功能的讨论不应该在功能分支中进行,而应该在单独的分支中进行,也就是在这里。

在你的描述中,根本不清楚如何通过引用和T型值来统一引用一个类方法。我不知道你在说什么,但我在那里说的正是这件事。

情况是这样的:我意识到,并不是所有的东西都可以按照论坛成员期望在该主题中看到的具体内容来定制。这里的讨论是(而且是在那里,所以我把它移到这里)关于一个相当具体的话题,我决定把它分出来,成为一个单独的主题。让大多数的功能有更多的普遍性和可理解性,在这里--类,棘手的工作方式,包括宏(对许多人来说是个难题)。

 
Ilya Malev:

谢谢你的澄清。我认为最好在一个单独的主题中进行讨论,这样就不会使主线中的所谓有价值的信息变得混乱。如果你决定移动帖子,我将讨论你把它们移到哪里。

从现在开始,让我们保持这种状态。只是--如果可能的话--把你在那里讨论的例子复制到你自己的帖子里,其中提到了那个例子(我很难弄清楚它从哪里开始)。或者,如果你不能再编辑你的帖子,那么在私下里告诉我从哪里粘贴什么。

 
Artyom Trishkin:

从现在起让它保持这种状态。只是--如果可能的话--把那里讨论过的例子复制到你的帖子里,其中提到了那个例子(我很难搞清楚这里的开头)。或者,如果你还不能编辑你的帖子,那就在私下里告诉我从哪里粘贴什么。

我已经从几个帖子前的那个主题中复制了代码到这里,所以不需要额外的行动,我认为。

 
Ilya Malev:

我已经从几个帖子前的那个主题中复制了代码,所以不需要额外的步骤。

很好。

 

关于通过模板和静态的接口主题的更新。更准确地说,不是接口,而是通过外部类实现的对任意类型的方便的可参数化操作。在这种情况下,比较(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上检查,我只是通过cis预处理程序进行测试,µl有其特殊性,所以如果有什么问题,请修改。

#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写几遍也不是问题。
原因: