CList sort() çalışması için CObject içindeki Compare() nasıl geçersiz kılınır?

 

Listelerin sıralanmasının mql5'te nasıl uygulanacağına dair herhangi bir belge bulamıyorum. CList'in CObject işaretçisinden Compare() öğesini çağırdığını görüyorum. Öyleyse, ana işaretçiden alt sınıf Compare() geçersiz kılınan yöntemini nasıl çağırabilirim?

Misal:

#include <Arrays\List.mqh>
//+------------------------------------------------------------------+
//| 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());
      
   }
  
}
 

Çözdüm, ancak başka birinin aynı sorunla karşılaşması durumunda çözümü burada bırakıyorum.

İmzasını değiştiren yöntem geçersiz kılma işleminden sonra const anahtar sözcüğünü unuttum.

int             Compare( const CObject *node, const int mode= 0 );

int             Compare( const CObject *node, const int mode= 0 ) const ;
 
nicholishen :

Çözdüm, ancak başka birinin aynı sorunla karşılaşması durumunda çözümü burada bırakıyorum.

İmzasını değiştiren yöntem geçersiz kılma işleminden sonra const anahtar sözcüğünü unuttum.

int             Compare( const CObject *node, const int mode= 0 );

int             Compare( const CObject *node, const int mode= 0 ) const ;

bunun için yöntemleri geçersiz kıldığınızda her zaman 'geçersiz kılma' anahtar sözcüğünü kullanmanız gerekir, bu şekilde yöntem imzası değiştirilirse derleyici bağırır:

int             Compare( const CObject *node, const int mode= 0 ) override const ;

'const' farkı nedeniyle derlenmeyecek

 

Ayrıca her iki durumda da 'sanal' anahtar kelimeyi unuttunuz:

virtual int             Compare( const CObject *node, const int mode= 0 ) override const ;
 
Amir Yacoby :

Ayrıca her iki durumda da 'sanal' anahtar kelimeyi unuttunuz:

virtual int             Compare( const CObject *node, const int mode= 0 ) override const ;
Hayır... Çocuğun olası herhangi bir türetilmiş tarafından geçersiz kılınmasını istemiyorum. Çalışmasını sağlamak için const'ı kaçırdım ve derleyici ile onaylamak için geçersiz kıldım
 
nicholishen :
Hayır... Çocuğun olası herhangi bir türetilmiş tarafından geçersiz kılınmasını istemiyorum. Çalışmasını sağlamak için const'ı kaçırdım ve derleyici ile onaylamak için geçersiz kıldım
Evet, ancak en azından CObject'te sanal anahtar kelimeye ihtiyacınız var
 
Amir Yacoby :
Evet, ancak en azından CObject'te sanal anahtar kelimeye ihtiyacınız var
Anladım... Kütüphanedeki temel sınıflarla uğraşmıyorum ve varsayılan olarak onda var, ama haklısın. Geçersiz kılma ipucu için teşekkürler!
 
nicholishen : Hayır... Çocuğun herhangi bir olası türetilmiş tarafından geçersiz kılınmasını istemiyorum.
  1. Sanal eklememek kötü bir uygulamadır, ancak gerekli değildir ( CObject dışında.)
  2. Sanal değişiklikleri hiçbir şey eklememek, türetilmiş bir sınıfta hala geçersiz kılınabilir.
  3. MT4/5'in son bir anahtar kelimesi yok
 
whroeder1 :
  1. Sanal eklememek kötü bir uygulamadır, ancak gerekli değildir (CObject dışında.)
  2. Sanal değişiklikleri hiçbir şey eklememek, türetilmiş bir sınıfta hala geçersiz kılınabilir.
Burada yanılıyorsun, whroeder1.
Tabana sanal eklememek polimorfizmi kaybetmenize neden olur - yöntem çalışma zamanında dinamik olarak değil statik olarak çağrılır.

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 sınıfındaki Sub sanala sahip değilse, gerçek bir b referansına sahip a tipi herhangi bir işaretçi çalışma zamanında asla b.Sub() öğesini çağırmaz.
 
Amir Yacoby :
Burada yanılıyorsun, whroeder1.
Tabana sanal eklememek polimorfizmi kaybetmenize neden olur - yöntem çalışma zamanında dinamik olarak değil statik olarak çağrılır.

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 virtual'a sahip değil, o zaman gerçek bir b referansına sahip a tipi herhangi bir işaretçi çalışma zamanında asla b.Sub() öğesini çağırmaz.
Doğru. Ayrıca sanal'ın atlanması, türetilmiş sınıfın geçersiz kılabileceği, ancak bir üst işaretçiden çağrılmayacağı anlamına gelir.
 
nicholishen :
Doğru. Ayrıca sanal'ın atlanması, türetilmiş sınıfın geçersiz kılabileceği, ancak bir üst işaretçiden çağrılmayacağı anlamına gelir.
bu tam olarak verdiğim örnek (: a ebeveyndir ve b.sub'u değil a.sub'u çağırır.