我想通了,但我把解决方案留在这里,以防其他人遇到同样的问题。
我忘了在方法覆盖后加上关键字 "const",从而改变了它的签名。
int Compare(const CObject *node,const int mode=0);
int Compare(const CObject *node,const int mode=0) const;
nicholishen:
我想通了,但我把解决方案留在这里,以防其他人遇到同样的问题。
我忘了在方法覆盖后加上关键字 "const",从而改变了它的签名。
int Compare(const CObject *node,const int mode=0);
int Compare(const CObject *node,const int mode=0) const;
为此,你必须在覆盖方法时使用关键字 "override",这样,如果方法的签名改变了,编译器就会大喊。
int Compare(const CObject *node,const int mode=0) override const;
因为 "const "的不同,它不会被编译。
而且你还忘记了这两种情况下的 "虚拟 "关键词。
virtual int Compare(const CObject *node,const int mode=0) override const;
Amir Yacoby:
不......我不希望这个子程序被任何可能的派生程序覆盖。我漏掉了const来使其工作,而覆盖是为了与编译器确认
而且你还忘记了这两种情况下的 "虚拟 "关键词。
virtual int Compare(const CObject *node,const int mode=0) override const;
Amir Yacoby:
是的,但至少在CObject中你需要虚拟关键词。
我知道了...我没有乱用库中的基类,它默认有这个功能,但你是对的。谢谢你的重写提示!
是的,但至少在CObject中你需要虚拟关键词。
whroeder1:
你错了,whroeder1。
|
不在基类中添加virtual将导致你失去多态性--该方法将被静态地调用,而不是在运行时动态地调用。
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();
}
如果a类中的Sub没有virtual,那么任何具有实际b引用的a类型的指针在运行时都不会调用b.Sub()。
{
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:
你错了,whroeder1。
不在基类中添加virtual将导致你失去多态性--方法将被静态地调用,而不是在运行时动态地调用。
正确。同样省略virtual意味着派生类可以覆盖,但不会被父类指针调用。
你错了,whroeder1。
不在基类中添加virtual将导致你失去多态性--方法将被静态地调用,而不是在运行时动态地调用。
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();
}
如果a类中的Sub没有虚拟,那么任何有实际b引用的a类型的指针在运行时都不会调用b.Sub()。{
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:
正确。另外,省略virtual意味着派生类可以覆盖,但不会被父指针调用。
这正是我给出的例子(:a是父类,它调用a.sub而不是b.sub。
正确。另外,省略virtual意味着派生类可以覆盖,但不会被父指针调用。
我找不到任何关于如何在mql5中实现Lists的排序的文档。我看到CList 从CObject指针中调用 Compare()。那么,我怎样才能从父指针中调用子类的Compare()重写方法呢?
例子。
//+------------------------------------------------------------------+
//| 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());
}
}