==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);
}
}
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);
}
// ...