OOP, Vorlagen und Makros in mql5, Feinheiten und Anwendungen - Seite 14

 
Artyom Trishkin:

1. Es ist besser, über etwas an dem Ort zu sprechen, an dem es ist, als darüber nachzudenken, wie der Moderator es machen würde. Andernfalls wurde alles in zwei Threads aufgeteilt, und selbst wenn der Moderator entscheidet, dass die Diskussion dort oder dort stattfinden soll, ist es sehr zeitaufwändig, die Diskussion so zu verschieben, dass die Reihenfolge und Bedeutung der Beiträge erhalten bleibt.

2) Über die Handlungen eines Moderators zu diskutieren, ist nicht jedermanns Sache... Es ist nicht jeder Nieser, aber wenn Sie ihn öffentlich herausfordern wollen, sei es zur Wiederherstellung der Ordnung oder zur Beruhigung eines Aufruhrs. Und wenn Sie eine Meinung haben, wer verbietet Ihnen, diese zu äußern? Vielleicht ist Ihre Meinung ein sehr vernünftiger Vorschlag, aber Sie trauen sich nicht, ihn auszusprechen, um nicht unter das ungeliebte Menü des Moderators zu fallen? Das ist also Blödsinn :)

Danke für die Klarstellung. Ich hielt es für das Beste, die Diskussion in einem separaten Thread zu führen, um die vermeintlich wertvollen Informationen im Hauptthread nicht zu überfrachten. Wenn Sie sich entschließen, die Stellen zu verschieben, werde ich darüber diskutieren, wohin Sie sie verschieben.

 
Ilya Malev:

Es ist ja nicht so, dass Sie ein Moderator sind und bestimmen können, in welchem Thread was angemessener ist. Und die Moderatoren haben bereits klargestellt, dass Diskussionen über Funktionen in einem separaten Zweig, d.h. hier, und nicht im Funktionszweig selbst stattfinden sollten.

Aus Ihrer Beschreibung geht überhaupt nicht hervor, wie man einheitlich auf eine Klassenmethode per Referenz und durch einen Wert vom Typ T verweisen kann. Ich weiß nicht, wovon Sie sprechen, aber ich habe genau darüber gesprochen.

Die Situation ist folgende: Ich habe erkannt, dass nicht alles auf die Besonderheiten zugeschnitten werden kann, die die Forumsmitglieder in diesem Thema erwarten. Die Diskussion hier (und sie war dort, also habe ich sie hierher verschoben) dreht sich um ein ziemlich spezifisches Thema, das ich in einen separaten Thread ausgelagert habe. Lassen Sie es mehr allgemein und verständlich für die Mehrheit der Funktionen, und hier - Klassen, knifflige Möglichkeiten der Arbeit mit ihnen, einschließlich Makros (was für ein Rätsel für viele).

 
Ilya Malev:

Danke für die Klarstellung. Ich hielt es für das Beste, die Diskussion in einem separaten Thread zu führen, um die vermeintlich wertvollen Informationen im Hauptthread nicht zu überfrachten. Wenn Sie sich entschließen, die Stellen zu verschieben, werde ich darüber diskutieren, wohin Sie sie verschieben.

So wollen wir es von nun an halten. Kopieren Sie einfach - wenn möglich - das Beispiel, das Sie dort erörtern, in Ihren eigenen Beitrag, der sich auf dieses Beispiel bezieht (ich habe Schwierigkeiten herauszufinden, wo es angefangen hat). Oder, wenn Sie Ihren Beitrag nicht mehr bearbeiten können, dann sagen Sie mir privat, wo ich was einfügen soll.

 
Artyom Trishkin:

So soll es von nun an bleiben. Kopieren Sie einfach - wenn möglich - das diskutierte Beispiel von dort in Ihren Beitrag, der sich auf dieses Beispiel bezieht (es ist schwer für mich herauszufinden, wie es hier angefangen hat). Oder, wenn Sie Ihren Beitrag noch nicht bearbeiten können, dann sagen Sie mir privat, wo ich was einfügen soll.

Ich habe den Code bereits vor ein paar Beiträgen aus diesem Thread hierher kopiert, so dass imho keine weiteren Maßnahmen erforderlich sind.

 
Ilya Malev:

Ich habe den Code bereits vor ein paar Beiträgen aus diesem Thread kopiert, so dass keine weiteren Schritte erforderlich sind.

Gut.

 

Update zum Thema Schnittstellen über Templates und Statik. Genauer gesagt, keine Schnittstellen, sondern bequem parametrisierbare Operationen für beliebige Typen, die durch externe Klassen implementiert werden. In diesem Fall der Vergleich (Comparer) und das Werfen (Caster).

Ich habe mich teilweise mit der vorherigen Kritik auseinandergesetzt, die "Interface"-Klasse (obwohl es kein Interface ist) wird nicht von der Parameterklasse geerbt (eine solche Methode hat sich nicht durchgesetzt...), und natürlich ohne dynamic_cast zu verwenden. Hoffentlich wird dieses Modell logischer aussehen.

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


 

Wie realistisch ist es, ein Makro für diesen Codeabschnitt zu schreiben?

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

Ich habe noch nicht über die Anzahl der Eingabevariablen ( input ) entschieden, ich bin müde, um den zugewiesenen Abschnitt zu korrigieren, das Makro für eine Zeile ist kein Problem, aber wie man es auf 10-15 Zeilen zu multiplizieren, weißich nicht

 
Igor Makanu:

Wie realistisch ist es, ein Makro für diesen Codeabschnitt zu erstellen?

haben noch nicht auf die Anzahl der Eingabevariablen ( Eingabe ) entschieden, müde, um den ausgewählten Teil zu korrigieren, das Makro für eine Zeile ist kein Problem, aber wie man es auf 10-15 Zeilen zu multiplizieren Ich weiß nicht

Ich muss gleich sagen, dass ich es nicht auf µl geprüft habe, ich habe es nur zum Testen durch einen sish-Präprozessor laufen lassen, µl hat Eigenheiten, wenn etwas fein abgestimmt werden muss.

#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

habe die Ausgabe (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);

zusätzliche Argumente, die Sie der ARGS-Liste spenden.

 
Igor Makanu:

Wie realistisch ist es, ein Makro für diesen Codeabschnitt zu schreiben?

Ich habe noch nicht über die Anzahl der Eingabevariablen ( input ) entschieden, ich bin müde, um den zugewiesenen Abschnitt zu korrigieren, das Makro für eine Zeile ist kein Problem, aber wie man es auf 10-15 Zeilen zu multiplizieren, weiß ich nicht

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

Bislang ist nur so etwas herausgekommen. Hätten die Entwickler eine variable Anzahl von Parametern hinzugefügt, wie in C, könnte es kürzer sein.

 
Vladimir Simakov:

Das ist alles, was mir bisher eingefallen ist. Würden die Entwickler wie in C eine variable Anzahl von Parametern einbauen, wäre es möglich, sie zu verkürzen.

Etwas, das ich zu kompliziert gemacht habe)).

Und lassen Sie sie den ersten benutzen, er ist wahrscheinlich der beste.

#define  TEST(dId)
Es ist kein Problem, TEST mehrmals zu schreiben.