Download MetaTrader 5

How to override Compare() in CObject so CList sort() works? - page 2

To add comments, please log in or register
Amir Yacoby
1316
Amir Yacoby  
whroeder1:
  1. MT4/5 doesn't have a final keyword

Also, this is wrong - there is a 'final' keyword in MQL5.

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

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

 this will not let CBar compile because CFoo is final.

honest_knave
Moderator
2326
honest_knave  
Amir Yacoby:
You are wrong here, whroeder1.
Not adding virtual in the base will cause you loosing the polymorphism - the method will be called statically and not dynamically at run time.

This was the caveat that whroeder1 mentioned.

whroeder1:
  1. Not adding the virtual is bad practice, but not required (except in the CObject.)
  2. Not adding the virtual changes nothing, it still can be overridden in a derived class.
  3. MT4/5 doesn't have a final keyword
honest_knave
Moderator
2326
honest_knave  
Amir Yacoby:

Also, this is wrong - there is a 'final' keyword in MQL5.

There is also a final keyword in MQL4, although the documentation doesn't show it (to my knowledge). Possibly it was mentioned in a build update.
Amir Yacoby
1316
Amir Yacoby  
It is not clear what does except in CObject means, but anyhow, points 1-2 are misleading:
1. It is not only bad practice, but required in every base (not only in CObject) if polymorphism is required.
2. It does change things - see 1.
3. final does exist.
Amir Yacoby
1316
Amir Yacoby  
honest_knave:
There is also a final keyword in MQL4, although the documentation doesn't show it (to my knowledge). Possibly it was mentioned in a build update.
Correct!
honest_knave
Moderator
2326
honest_knave  
Amir Yacoby:
Correct!
It was Build 1430 for MQL5. Probably around the same time for MQL4 with the common compiler.
Amir Yacoby
1316
Amir Yacoby  
honest_knave:
It was Build 1430 for MQL5. Probably around the same time for MQL4 with the common compiler.
Yes, that's where I got it from. Documentation lags many times, it is good practice to check the change lists.
Gustavo Hennemann
232
Gustavo Hennemann  

Hi guys,

I'm working in a class exactly like this post, but my "score" variable is a method. How to get its value?

This is the code from the begining of the post:

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


This is what I'm trying to do:

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

The question is, how to use getPrice() inside the method Compare()?

Thanks
Alain Verleyen
Moderator
34470
Alain Verleyen  
Gustavo Hennemann:

Hi guys,

I'm working in a class exactly like this post, but my "score" variable is a method. How to get its value?

This is the code from the begining of the post:


This is what I'm trying to do:

The question is, how to use getPrice() inside the method Compare()?

Thanks

Declare your getPrice() method with const keyword.

   double         getPrice() const
Gustavo Hennemann
232
Gustavo Hennemann  
Alain Verleyen:

Declare your getPrice() method with const keyword.

Hi @Alain Verleyen,

I changed the method getPrice(), insted using CopyClose() I'm using CopyBuffer(). This doesn't change the main objective.

So, if I use "const" keyword in the method getPrice(), a get the error: "'CopyBuffer' - no one of the overloads can be applied to the function call". I think this occurs because CopyBuffer is not a const method, and is not possible call non const method inside a const method.

To add comments, please log in or register