나는 그것을 알아 냈지만 다른 사람이 같은 문제에 직면 할 경우를 대비하여 여기에 솔루션을 남겨 두었습니다.
서명을 변경한 메서드 재정의 후 키워드 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에서는 virtual 키워드가 필요합니다.
알겠습니다... 라이브러리의 기본 클래스를 엉망으로 만들지 않고 기본적으로 라이브러리에 포함되어 있지만 맞습니다. 오버라이드 팁 감사합니다!
예, 하지만 적어도 CObject에서는 virtual 키워드가 필요합니다.
whroeder1 :
당신은 여기에서 틀렸습니다, whoroeder1.
|
기본에 가상을 추가하지 않으면 다형성을 잃게 됩니다. 메서드는 런타임에 동적으로 호출되지 않고 정적으로 호출됩니다.
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에 가상이 없으면 실제 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 :
당신은 여기에서 틀렸습니다, whoroeder1.
기본에 가상을 추가하지 않으면 다형성을 잃게 됩니다. 메서드는 런타임에 동적으로 호출되지 않고 정적으로 호출됩니다.
옳은. 또한 가상을 생략한다는 것은 파생 클래스가 재정의할 수 있지만 부모 포인터에서 호출되지 않는다는 것을 의미합니다.
당신은 여기에서 틀렸습니다, whoroeder1.
기본에 가상을 추가하지 않으면 다형성을 잃게 됩니다. 메서드는 런타임에 동적으로 호출되지 않고 정적으로 호출됩니다.
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 :
옳은. 또한 가상을 생략한다는 것은 파생 클래스가 재정의할 수 있지만 부모 포인터에서 호출되지 않는다는 것을 의미합니다.
이것은 정확히 내가 준 예입니다(: 는 부모이고 b.sub가 아니라 a.sub를 호출합니다.
옳은. 또한 가상을 생략한다는 것은 파생 클래스가 재정의할 수 있지만 부모 포인터에서 호출되지 않는다는 것을 의미합니다.
mql5에서 목록 정렬을 구현하는 방법에 대한 문서를 찾을 수 없습니다. 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());
}
}