Search code examples
c++polymorphismrtti

Designing a function that takes two abstract Base class objects as arguments, and does different things based on what Derived class the objects are


==EDIT 3==

In the end, I just added a checkIntersect(Shape) and checkIntersectSpecific(Circle/Polygon/Triangle) abstract methods to Shape and made them call my free (non-member) functions which were already implemented and in one place, while using some preprocessor and header tricks to save myself some duplicate code, in case I need to add other subclasses. For completion's sake, I'll mark Jefffrey's answer because his is the closest to what I did, however I'm thankful to all of you for showing me some cool stuff I actually didn't know about (function templates) and linking me to the other 2 questions which also proposed Visitor/Double dispatch as a solution.

Although I have to say, I hope we see multimethods in C++ soon.

==EDIT OVER==

So I have a base class Shape with its children: Triangle, Polygon, Circle and Vector and 10 static functions which take different pairs of the said children to check if they intersect. I also have a GameObject class, which has a Shape* member, and I want to implement collision detection. For that reason, I need something like a bool checkIntersection(Shape*, Shape*) to work for any kinds of shapes.

My original idea was to just have a (Shape, Shape) function and somehow check the types of the Shapes, then call an appropriate intersection check function, but I read that this is called RTTI and is generally considered bad. I read about Visitors and Double dispatch, but the way I see it, these don't really solve my problem. Then again, feel free to correct me if I'm wrong. Anyhow, now I'm stuck. I barely even managed to think of a title for this.

EDIT2: It doesn't necessarily need to be designed like this. I just need to to be somewhat easily maintainable, and preferrably without the need to update every Shape subclass if I decide to add another subclass later on.

EDIT: To clarify, here's what I'm trying to accomplish:

class Shape {...} //this is an abstract class
class Circle : public Shape {...}
class Triangle : public Shape {...} 
class Polygon : public Shape {...}

bool checkIntersection(const Shape &s1, const Shape &s2)
{
//Do some magic and call the right function
}

bool checkIntersection(const Circle &c, const Triangle &t) {..check...}
bool checkIntersection(const Circle &c, const Polygon &p) {...check...}
//and the rest of the functions for the different combinations

class GameObject
{
    Shape * shape;//Shape is abstract
    bool collidesWith(const GameObject& obj)
    {
        return checkIntersection(*this->shape, *obj.shape);
    }
}

Solution

  • You are trying to erase the type to then use the type. That makes little sense. Simply use overloading. No need to use a base class there:

    checkIntersection(const& Triangle, const& Polygon) { ... }
    checkIntersection(const& Triangle, const& Circle) { ... }
    // ...
    
    checkIntersection(const& Polygon p, const& Triangle t) {
        return checkIntersection(t, p);
    }
    // ...