I figured it out, but I'm leaving the solution here in case anyone else runs into the same problem.
I forgot to and the keyword const after the method override which changed its signature.
int Compare(const CObject *node,const int mode=0);
int Compare(const CObject *node,const int mode=0) const;
nicholishen:
I figured it out, but I'm leaving the solution here in case anyone else runs into the same problem.
I forgot to and the keyword const after the method override which changed its signature.
int Compare(const CObject *node,const int mode=0);
int Compare(const CObject *node,const int mode=0) const;
for this you have to use the keyword 'override' always when you override methods, this way the compiler shouts if the method signature is changed:
int Compare(const CObject *node,const int mode=0) override const;
it won't compile because of the 'const' difference
And you also forgot the 'virtual' keyword on both cases:
virtual int Compare(const CObject *node,const int mode=0) override const;
Amir Yacoby:
No... I don't want the child to be overridden by any possible derived. I missed const to make it work, and override to confirm with compiler
And you also forgot the 'virtual' keyword on both cases:
virtual int Compare(const CObject *node,const int mode=0) override const;
Amir Yacoby:
Yes, but at least in CObject you need the virtual keyword
I got ya... I don't mess with the base classes in the library and it has it by default, but you're correct. Thanks for the override tip!
Yes, but at least in CObject you need the virtual keyword
whroeder1:
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.
class a
{
public:
void Sub()
{
Print("a.sub");
}
};
class b : public a
{
public:
void Sub()
{
Print("b.sub");
}
};
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//---
clsa *a;
clsa=new b;
clsa.Sub();
}
if Sub in class a does not have the virtual, then any pointer of type a that has an actual b reference will never call the b.Sub() at run time.
{
public:
void Sub()
{
Print("a.sub");
}
};
class b : public a
{
public:
void Sub()
{
Print("b.sub");
}
};
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//---
clsa *a;
clsa=new b;
clsa.Sub();
}
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.
Correct. Also omitting virtual means that derived class can override, but won't be called from a parent pointer.
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.
class a
{
public:
void Sub()
{
Print("a.sub");
}
};
class b : public a
{
public:
void Sub()
{
Print("b.sub");
}
};
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//---
a *clsa;
clsa=new b;
clsa.Sub();
}
is Sub in class a does not have the virtual, then any pointer of type a that has an actual b reference will never call the b.Sub() at run time.{
public:
void Sub()
{
Print("a.sub");
}
};
class b : public a
{
public:
void Sub()
{
Print("b.sub");
}
};
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//---
a *clsa;
clsa=new b;
clsa.Sub();
}
nicholishen:
Correct. Also omitting virtual means that derived class can override, but won't be called from a parent pointer.
which is exactly the example I gave (: a is the parent, and it calls a.sub and not b.sub.
Correct. Also omitting virtual means that derived class can override, but won't be called from a parent pointer.
You are missing trading opportunities:
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
Registration
Log in
You agree to website policy and terms of use
If you do not have an account, please register
I can't find any documentation on how to implement the sorting of Lists in mql5. I see that CList calls the Compare() from the CObject pointer. So how can I call the child class Compare() overridden method from the parent pointer?
Example:
//+------------------------------------------------------------------+
//| 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;
}
void OnStart()
{
//---
CList list;
list.Add( new PriceScore(100,500));
list.Add( new PriceScore(1,5));
list.Add( new PriceScore(13,5000));
list.Add( new PriceScore(987987,567));
list.Add( new PriceScore(98798778,1));
PriceScore *node = NULL;
Print("-------------------",TimeCurrent(),"--------------------");
for(int i=0;i<list.Total();i++)
{
node = list.GetNodeAtIndex(i);
Print("Price = ",node.Price(),", Score = ",node.Score());
}
list.Sort(1); //Can't call overriden child method'
Print("-------------------SORTED--------------------");
for(int i=0;i<list.Total();i++)
{
node = list.GetNodeAtIndex(i);
Print("Price = ",node.Price(),", Score = ",node.Score());
}
}