Imagine an abstract base class of Shape , with derived classes of Circle and Rectangle .
class Shape {}; class Circle : public Shape {}; class Rectangle : public Shape {};
I need to determine if two shapes are equal if I have two Shape* pointers. (This is because I have two instances of vector<Shape*> , and I want to see if they have the same shape.)
The recommended way to do this is double dispatch . What I came up with is (it’s very simplified here, so the forms are equal to all other forms of the same type):
class Shape { public: virtual bool equals(Shape* other_shape) = 0; protected: virtual bool is_equal(Circle& circle) { return false; }; virtual bool is_equal(Rectangle& rect) { return false; }; friend class Circle;
This works, but I have to add a separate equals and friend function to the Shape for each derived class. Then I need to copy-paste the exact same equals function into each derived class. This is an awful lot of patterns, say 10 different shapes!
Is there an easier way to do this?
dynamic_cast out of the question; too slow. (Yes, I compared this. Speed matters in my application.)
I tried this, but it does not work:
class Shape { public: virtual bool equals(Shape* other_shape) = 0; private: virtual bool is_equal(Shape& circle) { return false; }; }; class Circle : public Shape { public: virtual bool equals(Shape* other_shape) { return other_shape->is_equal(*this); }; private: virtual bool is_equal(Circle& circle) { return true; }; }; class Rectangle : public Shape { public: virtual bool equals(Shape* other_shape) { return other_shape->is_equal(*this); }; private: virtual bool is_equal(Rectangle& circle) { return true; }; };
equals() always returns false, even in the same form. Sending always seems to select the underlying function is_equal(Shape&) , even if a “more specific” match is available. This probably makes sense, but I don't understand how to send C ++ well enough to understand why.
c ++ inheritance oop double-dispatch
Adam ernst
source share