Luc is right on with using the Visitor pattern, I'm just expanding on that by giving an example of how you could do it.
#include <iostream>
#include <conio.h>
using namespace std;
class SpaceObject;
class SpaceShip;
class GiantSpaceShip;
class Asteroid;
class ExplodingAsteroid;
class SpaceObject {
public:
virtual void CollideWith(SpaceObject*) {}
virtual void CollideWith(SpaceShip*) {}
virtual void CollideWith(GiantSpaceShip*) {}
virtual void CollideWith(Asteroid*) {}
virtual void CollideWith(ExplodingAsteroid*) {}
};
class Asteroid : public SpaceObject {
public:
virtual void CollideWith(SpaceObject* o) { o->CollideWith(this); }
virtual void CollideWith(SpaceShip *) { cout << "Asteroid hit a SpaceShip" << endl; }
virtual void CollideWith(GiantSpaceShip *) { cout << "Asteroid hit a GiantSpaceShip" << endl; }
};
class ExplodingAsteroid : public Asteroid {
public:
virtual void CollideWith(SpaceObject* o) { o->CollideWith(this); }
virtual void CollideWith(SpaceShip *) { cout << "ExplodingAsteroid hit a SpaceShip" << endl; }
virtual void CollideWith(GiantSpaceShip *) { cout << "ExplodingAsteroid hit a GiantSpaceShip" << endl; }
};
class SpaceShip : public SpaceObject {
public:
virtual void CollideWith(SpaceObject* o) { o->CollideWith(this); }
virtual void CollideWith(Asteroid* o) { o->Asteroid::CollideWith(this); }
virtual void CollideWith(ExplodingAsteroid* o) { o->ExplodingAsteroid::CollideWith(this); }
};
class GiantSpaceShip : public SpaceShip {
public:
virtual void CollideWith(SpaceObject* o) { o->CollideWith(this); }
virtual void CollideWith(Asteroid* o) { o->Asteroid::CollideWith(this); }
virtual void CollideWith(ExplodingAsteroid* o) { o->ExplodingAsteroid::CollideWith(this); }
};
int main()
{
SpaceObject* s = new GiantSpaceShip();
SpaceObject* a = new ExplodingAsteroid();
a->CollideWith(s);
getch();
return 0;
}