Wie zu überschreiben Compare() in CObject so CList sort() funktioniert? - Seite 2

 
whroeder1:
  1. MT4/5 hat kein Schlüsselwort final

Außerdem ist dies falsch - es gibt ein 'final' Schlüsselwort in MQL5.

class CFoo final
  {
  //--- class body
  };

class CBar : public CFoo
  {
  //--- class body
  };

Damit lässt sich CBar nicht kompilieren, weil CFoo final ist.

 
Amir Yacoby:
Du liegst hier falsch, whroeder1.
Wenn Sie in der Basisklasse kein virtual hinzufügen, verlieren Sie die Polymorphie - die Methode wird statisch und nicht dynamisch zur Laufzeit aufgerufen.

Dies war der Vorbehalt, den whroeder1 erwähnte.

whroeder1:
  1. Das Nichthinzufügen der Virtualität ist eine schlechte Praxis, aber nicht erforderlich(außer im CObject).
  2. Das Nichthinzufügen des virtuellen ändert nichts, es kann immer noch in einer abgeleiteten Klasse überschrieben werden.
  3. MT4/5 hat kein final-Schlüsselwort
 
Amir Yacoby:

Außerdem ist dies falsch - in MQL5 gibt es ein Schlüsselwort "final".

Es gibt auch ein final-Schlüsselwort in MQL4, obwohl die Dokumentation es nicht zeigt (meines Wissens). Möglicherweise wurde es in einem Build-Update erwähnt.
 
Es ist nicht klar, was "except in CObject " bedeutet, aber die Punkte 1-2 sind auf jeden Fall irreführend:
1. Es ist nicht nur schlechte Praxis, sondern in jeder Basis (nicht nur in CObject) erforderlich, wenn Polymorphismus erforderlich ist.
2. Es ändert die Dinge - siehe 1.
3. final existiert.
 
honest_knave:
Es gibt auch ein letztes Schlüsselwort in MQL4, obwohl die Dokumentation es (meines Wissens) nicht zeigt. Möglicherweise wurde es in einem Build-Update erwähnt.
Richtig!
 
Amir Yacoby:
Richtig!
Es war Build 1430 für MQL5. Wahrscheinlich etwa zur gleichen Zeit für MQL4 mit dem gemeinsamen Compiler.
 
honest_knave:
Es war Build 1430 für MQL5. Wahrscheinlich etwa zur gleichen Zeit für MQL4 mit dem gemeinsamen Compiler.
Ja, von dort habe ich es. Die Dokumentation hinkt oft hinterher, es ist gute Praxis, die Änderungslisten zu prüfen.
 

Hallo Leute,

Ich arbeite in einer Klasse genau wie dieser Beitrag, aber meine "score" Variable ist eine Methode. Wie bekomme ich ihren Wert?

Dies ist der Code vom Anfang des Beitrags:

#include <Arrays\List.mqh>
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+

class PriceScore : public CObject
{
protected:
   int price;
   int score;
public:
                  PriceScore(void){}
                  PriceScore(int p, int s):price(p),score(s){}
                  ~PriceScore(void){}
   int            Compare(const CObject *node,const int mode=0);
   void           Price(const int p){price = p;}
   int            Price() const {return price;}
   void           Score(const int s){score = s;}
   int            Score() const {return score;}
  
};

int PriceScore::Compare(const CObject *node,const int mode=0) //Can't call this override from CList
{
   PriceScore *pc = (PriceScore*)node;
   Print(__FUNCTION__,":Compare called. Incoming: ",pc.Score()," This: ", score); //Doesn't log because this isn't called from CObject'
   if(pc.Score()< score)return 1;
   else if(pc.Score()> score) return -1;
   else return 0;
}


Dies ist, was ich versuche zu tun:

#include <Arrays\List.mqh>
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+

class PriceScore : public CObject
{
protected:
   int price;
   int score;
public:
                  PriceScore(void){}
                  PriceScore(int p, int s):price(p),score(s){}
                  ~PriceScore(void){}
   virtual int    Compare(const CObject *node,const int mode=0) override const;
   void           setPrice(const int p){price = p;}
   //this is a simple function to get the close price of today
   double         getPrice()
                  {
                     double arrayPrice[1];
                     CopyClose(mySymbol, myTimeFrame, today, 1, arrayPrice);
                     return arrayPrice[0];
                  }
   void           Score(const int s){score = s;}
   int            Score() const {return score;}
  
};

int PriceScore::Compare(const CObject *node,const int mode=0) const
{
   PriceScore *pc = (PriceScore*)node;
   Print(__FUNCTION__,":Compare called. Incoming: ",pc.Score()," This: ", score);
   
   if(pc.Score() < getPrice())      //here is the problem, how to use getPrice()???
      return 1;
   else if(pc.Score() > getPrice()) //here is the problem, how to use getPrice()???
      return -1;
   else
      return 0;
}

Die Frage ist, wie man getPrice() innerhalb der Methode Compare() verwenden kann?

Danke
 
Gustavo Hennemann:

Hallo Leute,

Ich arbeite in einer Klasse genau wie dieser Beitrag, aber meine "score" Variable ist eine Methode. Wie bekomme ich ihren Wert?

Dies ist der Code vom Anfang des Beitrags:


Das ist, was ich versuche zu tun:

Die Frage ist, wie man getPrice() innerhalb der Methode Compare() verwendet?

Danke

Deklarieren Sie die Methode getPrice() mit dem Schlüsselwort const.

   double         getPrice() const
 
Alain Verleyen:

Deklarieren Sie die Methode getPrice() mit dem Schlüsselwort const.

Hallo @Alain Verleyen,

ich habe die Methode getPrice() geändert, anstelle von CopyClose() verwende ich CopyBuffer(). Das ändert aber nichts am eigentlichen Ziel.

Wenn ich also das Schlüsselwort "const" in der Methode getPrice() verwende, erhalte ich die Fehlermeldung: "'CopyBuffer' - keine der Überladungen kann auf den Funktionsaufruf angewendet werden". Ich denke, dies tritt auf, weil CopyBuffer keine const-Methode ist und es nicht möglich ist, eine nicht-konst-Methode innerhalb einer const-Methode aufzurufen.