OOP, modelli e macro in mql5, sottigliezze e usi - pagina 14

 
Artyom Trishkin:

1. È meglio parlare di qualcosa nel luogo in cui si trova, piuttosto che pensare a come lo farebbe il moderatore. Altrimenti, tutto si è davvero confuso in due thread e ora, anche se il moderatore decide che la discussione deve stare lì o lì, è un compito molto ingombrante spostare la discussione normalmente con l'ordine dei post e il loro significato conservato.

2) Discutere le azioni di un moderatore non è ogni starnuto... Non è ogni starnuto, ma se volete sfidarlo pubblicamente, che sia per ristabilire l'ordine o per calmare una frenesia. E se avete un'opinione, chi vi proibisce di esprimerla? Forse la tua opinione è un suggerimento molto razionale, ma hai paura di dirlo, per non cadere sotto il menu non amato del moderatore? Quindi è una stronzata :)

Grazie per il chiarimento. Ho pensato che fosse meglio avere la discussione in un thread separato in modo da non ingombrare le informazioni presumibilmente preziose nel thread principale. Se decidete di spostare i post, discuterò dove spostarli.

 
Ilya Malev:

Non è che sei ancora un moderatore, per determinare in quale thread ciò che è più appropriato. E i moderatori hanno già chiarito che la discussione delle caratteristiche dovrebbe essere in un ramo separato, cioè qui, piuttosto che nel ramo delle caratteristiche stesso.

Non è affatto chiaro nella vostra descrizione come riferirsi uniformemente a un metodo di classe per riferimento e per un valore di tipo T. Non so di cosa stiate parlando, ma io stavo parlando proprio di questo.

Ecco la situazione: mi sono reso conto che non tutto può essere adattato alle specifiche che i membri del forum si aspettano di vedere in quel thread. La discussione qui è (ed era lì, quindi l'ho spostata qui) su un argomento abbastanza specifico, che ho deciso di separare in un thread separato. Lasciate che ci sia più generale e comprensibile per la maggior parte delle caratteristiche, e qui - classi, modi complicati di lavorare con loro, tra cui macro (che un puzzle per molti).

 
Ilya Malev:

Grazie per il chiarimento. Ho pensato che fosse meglio avere la discussione in un thread separato in modo da non ingombrare le informazioni presumibilmente preziose nel thread principale. Se decidete di spostare i post, discuterò dove spostarli.

Continuiamo così d'ora in poi. Solo - se possibile - copiate l'esempio che state discutendo da lì nel vostro post, che fa riferimento a quell'esempio (ho difficoltà a capire da dove è iniziato). Oppure, se non puoi più modificare il tuo post, allora dimmi in privato da dove incollare cosa.

 
Artyom Trishkin:

Che rimanga così d'ora in poi. Basta - se possibile - copiare l'esempio discusso da lì nel tuo post, che fa riferimento a quell'esempio (è difficile per me capire da dove è partito qui). Oppure, se non puoi già modificare il tuo post, allora dimmi in privato da dove incollare cosa.

Ho già copiato il codice qui da quel thread un paio di post fa, quindi non è necessaria alcuna azione aggiuntiva, imho.

 
Ilya Malev:

Ho già copiato il codice da quel thread un paio di post fa, quindi non sono necessari ulteriori passaggi.

Bene.

 

Aggiornamento sull'argomento delle interfacce tramite modelli e statica. Per essere più precisi, non interfacce, ma piuttosto operazioni comodamente parametrizzabili su tipi arbitrari, implementate attraverso classi esterne. In questo caso, il confronto (Comparer) e la fusione (Caster).

Ho parzialmente affrontato la critica precedente, la classe "interfaccia" (anche se non è un'interfaccia) non è ereditata dalla classe parametro (un tale metodo non ha preso piede...), e senza usare dynamic_cast ovviamente. Speriamo che questo modello sia più logico.

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


 

Quanto è realistico scrivere una macro per questa sezione di codice?

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

Non ho ancora deciso il numero di variabili di input (input), sono stanco di correggere la sezione allocata, la macro per una linea non è un problema, ma come moltiplicarla per 10-15 lineenon lo so

 
Igor Makanu:

Quanto è realistico scrivere una macro per questa sezione di codice?

non hanno ancora deciso il numero di variabili di input (input), stanco di correggere la parte selezionata, la macro per una linea non è un problema, ma come moltiplicare a 10-15 linee non so

Devo dire subito che non l'ho controllato su µl, l'ho solo eseguito attraverso il preprocessore cis per testarlo, µl ha delle particolarità, quindi se qualcosa va storto, modificatelo.

#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

ha ottenuto l'output (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);

argomenti aggiuntivi si / donare alla lista ARGS.

 
Igor Makanu:

Quanto è realistico scrivere una macro per questa sezione di codice?

Non ho ancora deciso il numero di variabili di input (input), sono stanco di correggere la sezione allocata, la macro per una linea non è un problema, ma come moltiplicarla per 10-15 linee non lo so

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

Finora, solo così venire con. Se gli sviluppatori avessero aggiunto un numero variabile di parametri, come in C, potrebbe essere più breve.

 
Vladimir Simakov:

Finora, questo è tutto quello che ho trovato. Se gli sviluppatori avvitassero un numero variabile di parametri, come in C, sarebbe possibile renderlo più breve.

Qualcosa che ho complicato eccessivamente )).

E lasciate che usino il primo, probabilmente è il migliore.

#define  TEST(dId)
Non è un problema scrivere TEST più volte.