There are two classes: Point , Pixel . Pixel derived from Point .
There is an array of pointers Point* , which stores pointers to objects of type Point and Pixel .
You need to sort the array like this:

  • When comparing Point and Point - comparing the results of p1.dist() and p2.dist()
  • When comparing Point and Pixel - comparing the results of p1.dist() and p2.dist()
  • When comparing Pixel and Point - comparing the results of p1.dist() and p2.dist()
  • When comparing Pixel and Pixel - comparing the results of p1.dist() and p2.dist() . If they are the same, then compare the color ( string ) of two pixels.

My decision:

In the Pixel and Point classes, there are less overloaded virtual functions (class methods) that are accepted by the parameter const Pixel & and const Point & , respectively.

Problem:
Pointer dereferencing of Point does not return a dynamic type, but const Point & , therefore when called:

 Point* p1=new Point; Point* p2=new Pixel; return *p1<*p2; 

For the operand p1 , the function less is called from the class of the corresponding dynamic type p1 due to the mechanism of polymorphism. But regardless of the dynamic type of p2 , the overloaded bool less (const Point &) function is always called, instead of bool less (const Pixel &)

I will explain a little:

 *p1<*p2; //Point::less(const Point&) вместо Point::less(const Pixel&) *p2<*p1; //Pixel::less(const Point&) *p1<*p1; //Point::less(const Point&) *p2<*p2; //Pixel::less(const Point&) вместо Pixel::less(const Pixel&) 
  • dist() is virtual? If not, can it be made virtual? Just if it is virtual, compare the result of its call through a pointer to a Point and do not suffer ... - Harry
  • @Harry It does not allow to make 4 clauses of the condition - Denis
  • Frankly, I did not understand why. - Harry
  • The @Harry dist () method is the distance from the origin. And if it is the same, then for the pixels you need to compare more and color. I will not be in the method for obtaining the distance to compare colors - semantically wrong. - Denis
  • Why not? Any comparison <=> is based on the concept of distance, and distance is just some scalar function of two points in a vector space. In order for such a function to be the distance, it is just necessary that it be non-negative and symmetric with respect to the arguments. So do not invent yourself restrictions. - Bwana The Master

1 answer 1

Well, try this comparator:

 class Point { public: virtual int dist() const; }; class Pixel: public Point { public: virtual int dist() const; string color() const; }; bool less(const Point* p1, const Point* p2) { if (p1->dist() < p2->dist()) return true; if (p1->dist() > p2->dist()) return false; const Pixel* x1 = dynamic_cast<const Pixel*>(p1); const Pixel* x2 = dynamic_cast<const Pixel*>(p2); if (!x1 || !x2) return false; return x1->color() < x2->color(); }