Я разобрался с этим, но оставляю решение здесь на случай, если кто-то еще столкнется с такой же проблемой.
Я забыл добавить ключевое слово const после переопределения метода, что изменило его сигнатуру.
Я разобрался с этим, но оставляю решение здесь на случай, если кто-то еще столкнется с такой же проблемой.
Я забыл добавить ключевое слово const после переопределения метода, что изменило его сигнатуру.
Для этого нужно использовать ключевое слово 'override' всегда, когда вы переопределяете методы, таким образом компилятор кричит, если сигнатура метода изменена:
он не будет компилироваться из-за разницы в 'const'.
И вы также забыли ключевое слово 'virtual' в обоих случаях:
И вы также забыли ключевое слово 'virtual' в обоих случаях:
Да, но по крайней мере в CObject вам нужно виртуальное ключевое слово.
nicholishen: Нет... Я не хочу, чтобы дочерний класс был переопределен любым возможным производным классом. |
|
|
Не добавление virtual в базу приведет к потере полиморфизма - метод будет вызываться статически, а не динамически во время выполнения.
{
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();
}
Вы ошибаетесь, whroeder1.
Если не добавить virtual в базу, то вы потеряете полиморфизм - метод будет вызываться статически, а не динамически во время выполнения.
{
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();
}
Правильно. Также опущение virtual означает, что производный класс может переопределять, но не будет вызываться из родительского указателя.

- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Я не могу найти документацию о том, как реализовать сортировку списков в mql5. Я вижу, что CList вызывает Compare() из указателя CObject. Как же я могу вызвать переопределенный метод 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());
}
}