为什么双重调度在C ++中不起作用?

时间:2010-05-04 09:19:11

标签: 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;   
}

如何在C ++中启用双重调度?

2 个答案:

答案 0 :(得分:4)

这不是单一调度,而是 double 调度:您希望该方法既依赖于调用对象的实际/实际类型,又依赖于参数的实际/实际类型

Visitor design pattern可以解决此问题。

答案 1 :(得分:2)

Luc正确地使用了访问者模式,我只是通过举例说明如何做到这一点来扩展它。

#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;
}