私はそれを理解しましたが、他の誰かが同じ問題に遭遇した場合のために、ここに解決策を残しておきます。
私は、シグネチャを変更したメソッドのオーバーライドの後に、キーワード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:
いや、子プロセスが派生してオーバーライドされるのは困るんだ。コンストラクタで動作するようにし、オーバーライドでコンパイラに確認しました。
また、どちらの場合も「バーチャル」というキーワードを忘れていますね。
virtual int Compare(const CObject *node,const int mode=0) override const;
Amir Yacoby:
しかし、少なくとも CObject では、virtual キーワードが必要です。
そうなんだ・・・。私はライブラリのベースクラスをいじらないので、デフォルトで持っていますが、あなたの言うとおりです。オーバーライドのヒントありがとうございました
しかし、少なくとも CObject では、virtual キーワードが必要です。
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を省略すると、派生クラスはオーバーライドできるが、親ポインタから呼び出されることはない。
whroeder1 さん、あなたは間違っています。
メソッドは静的に呼び出され、実行時に動的に呼び出されることはないのです。
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が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()
{
//---
a *clsa;
clsa=new b;
clsa.Sub();
}
nicholishen:
その通りです。また、virtualを省略すると、派生クラスはオーバーライドできますが、親ポインタから呼び出されることはありません。
というのは、まさに私が挙げた例です(: a が親で、a.sub を呼び出し、b.sub は呼び出さない。
その通りです。また、virtualを省略すると、派生クラスはオーバーライドできますが、親ポインタから呼び出されることはありません。
取引の機会を逃しています。
- 無料取引アプリ
- 8千を超えるシグナルをコピー
- 金融ニュースで金融マーケットを探索
mql5でListのソートを実装する方法について、ドキュメントが見当たりません。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());
}
}