Why doesn't double dispatch work in C ++?
#include<iostream.h>
#include<conio.h>
using namespace std;
class SpaceShip {};
class GiantSpaceShip : public SpaceShip {};
class Asteroid {
public:
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(SpaceShip *) {
cout << "ExplodingAsteroid hit a SpaceShip" << endl;
}
virtual void CollideWith(GiantSpaceShip *) {
cout << "ExplodingAsteroid hit a GiantSpaceShip" << endl;
}
};
int main()
{
SpaceShip * s = new GiantSpaceShip();
Asteroid * a = new ExplodingAsteroid();
a->CollideWith(s);
getch();
return 0;
}
How do I enable double dispatch in C ++?
+2
a source to share
2 answers
This is not a separate dispatch, but a double dispatch: you want the method to depend on both the actual / real type of the object it is called on and the actual / actual type of the argument.
This problem can be solved with a visitor design template .
+4
a source to share
Luke directly using the visitor template, I'm just expanding on this by giving an example of how you could do this.
#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;
}
+2
a source to share