How to implement multilevel inheritance to IComparable interface? - page 2

 
Because you defined the template as P* not X*. Therefore, when you change the function signature from P* to X* you are not overriding it and instead you are overloading it so it will never get called. 
 
nicholi shen:
Because you defined the template as P* not X*. Therefore, when you change the function signature from P* to X* you are not overriding it and instead you are overloading it so it will never get called. 

you are right. the problem was the signature. using a template at the top took care of it. now both X and Y object could be sorted in an arraylist. but I think that now you can't have a P list because of the general T typename. anyway P was meant to be an abstract class, I don't want to instantiate it. thanks that have solved my problem completely.

//+------------------------------------------------------------------+
//|                                                      ProjectName |
//|                                      Copyright 2020, CompanyName |
//|                                       http://www.companyname.net |
//+------------------------------------------------------------------+
#include <generic/arraylist.mqh>

template<typename T>
class P : public IComparable<T> {

public:
   int x;
   int y;
   P(): x(1), y(2) {}
   virtual int get_sort_value() {return 0;};
   virtual int HashCode() {
      return int(pow(this.x, 2) + pow(this.y, 2));
   }
   virtual bool Equals(T other) {
      return (this.get_sort_value() == other.get_sort_value());
   }

   int Compare(T other) {
      if (this.get_sort_value() > other.get_sort_value()) return 1;
      if (this.get_sort_value() < other.get_sort_value()) return -1;
      return 0;
   }
};

class X : public P<X*> {
public:
   virtual int get_sort_value() {
      return this.x;
   }
};

class Y : public P<Y*> {
public:
   virtual int get_sort_value() {
      return this.y;
   }
};
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnStart() {
   //CArrayList<P*> list;
   //list.Add(new X());
   //list.Add(new Y());
   //list.Sort();

   CArrayList<X*> list2;
   X* x1 = new X();
   x1.x = 20;
   list2.Add(x1);
   X* x2 = new X();
   x2.x = 2;
   list2.Add(x2);
   X* x3 = new X();
   x3.x = 12;
   list2.Add(x3);

   list2.Sort(); //works
}
//+------------------------------------------------------------------+
 
Null_Pointer:

you are right. the problem was the signature. using a template at the top took care of it. now both X and Y object could be sorted in an arraylist. but I think that now you can't have a P list because of the general T typename. anyway P was meant to be an abstract class, I don't want to instantiate it. thanks that have solved my problem completely.

...and now you have to be concerned about all those memory leaks. It's better to use CArrayObj with a CObject subclass because not only does it handle all the memory cleanup for you but it is also faster than CArrayList. I can only think of one situation where overriding IComarable might be beneficial and that would be using the complex object as a hashed key, but even then I can't help but to think that there's a better pattern. 

 
nicholi shen:

...and now you have to be concerned about all those memory leaks. It's better to use CArrayObj with a CObject subclass because not only does it handle all the memory cleanup for you but it is also faster than CArrayList. I can only think of one situation where overriding IComarable might be beneficial and that would be using the complex object as a hashed key, but even then I can't help but to think that there's a better pattern. 

yes, the hash key is the only reason I stuck with the IComparable, taking the memory management ability of CArrayObj into account, it is surly a better choice (which I didn't know of before you mentioned it). also the speed of search in lists is an issue to think about. but the use of the generic data collections (like hashset, hashmap and sortedmap) is unavoidable in my project. is there any clean way to implement these data collections without the need to code them from scratch?

 
Null_Pointer:

yes, the hash key is the only reason I stuck with the IComparable, taking the memory management ability of CArrayObj into account, it is surly a better choice (which I didn't know of before you mentioned it). also the speed of search in lists is an issue to think about. but the use of the generic data collections (like hashset, hashmap and sortedmap) is unavoidable in my project. is there any clean way to implement these data collections without the need to code them from scratch?

If you're needing to map an object to another object with a dictionary intermediary then perhaps you might consider a different pattern, like storing refs to each-other in the classes themselves. 

Reason: