I want to create a collision system, in which a base class represents an object in the scene, implements all the collision logic, and when a collision is detected, a derived class function is called for the program logic. The problem that i am facing, is that the base class needs to know about all the derived classes, for the dispatch in different functions to work correctly.
Example, base class, OnCollisionDetected
will be overridden by the derived class to handle the collision
#include <iostream>
class BasePhysicsObject {
public:
void Collides(BasePhysicsObject * another_object) {
/* ... */
bool collides = true;
if (collides) this->OnCollisionDetected(another_object);
return;
}
/* Function to be overriden */
virtual void OnCollisionDetected(BasePhysicsObject * another_object) = 0;
};
Two dummy classes in the scene, with the function OnCollisionDetected(BasePhysicsObject * another_object)
overridden, to dispatch the call to the appropriate function based on the this
argument.
class Fire;
class Player : public BasePhysicsObject {
public:
virtual void OnCollisionDetected(BasePhysicsObject * another_object) {
/* double dispatch to specific implementation */
another_object->OnCollisionDetected(this);
}
virtual void OnCollisionDetected(Fire * fire) {
/* Collision with fire object*/
}
};
class Fire : public BasePhysicsObject {
public:
virtual void OnCollisionDetected(BasePhysicsObject * another_object) {
/* double dispatch to specific implementation */
another_object->OnCollisionDetected(this);
}
virtual void OnCollisionDetected(Player * player) {
/* Collision with player object */
}
};
Main function creates two objects, and checks their collision.
int main(int argc, char ** argv){
Player * player = new Player();
Fire * fire = new Fire();
fire->Collides(player);
}
What ends up happening, is that Fire::OnCollisionDetected(BasePhysicsObject * another_object)
which is called from Collides()
does not call the function with the derived class as argument i.e Player::OnCollisionDetected(Fire * fire)
, but rather the Player::OnCollisionDetected(BasePhysicsObject * another_object)
which again calls back the function, resulting in a stack overflow.
As i am given to understand, in order for double dispatch to work, I need to declare OnCollisionDetected(Derived *)
in the base class for all derived classes, but this is a daunting solution. Is there any other way to do it?