#include
#include
#include
#include
#include #include using namespace std;////class SpaceStation;//class Asteroid;//class SpaceShip;class CollisionWithUnknownObject {public: CollisionWithUnknownObject() { std::cout << "unknown error" << std::endl; } //...};class GameObject {public: virtual void collide(GameObject& otherObject) = 0; //...};//The class SpaceShip Declarationclass SpaceShip: public GameObject {public: virtual void collide(GameObject& otherObject); virtual void hitSpaceShip(GameObject& spaceShip); virtual void hitSpaceStation(GameObject& spaceStation); virtual void hitAsteroid(GameObject& asteroid); //... private: typedef void (SpaceShip::*HitFunctionPtr)(GameObject& what); static HitFunctionPtr lookup(GameObject& what); typedef map< string, HitFunctionPtr > HitMap; static HitMap* initializeCollisionMap();};//The class SpaceStation Declarationclass SpaceStation: public GameObject {public: virtual void collide(GameObject& otherObject); virtual void hitSpaceShip(GameObject& otherObject); virtual void hitSpaceStation(GameObject& otherObject); virtual void hitAsteroid(GameObject& otherobject); //...private: typedef void (SpaceStation::*HitFunctionPtr)(GameObject& what); static HitFunctionPtr lookup(GameObject& what); typedef map< string, HitFunctionPtr > HitMap; static HitMap* initializeCollisionMap();};//The class Asteroid Declarationclass Asteroid: public GameObject {public: virtual void collide(GameObject& otherObject); virtual void hitSpaceShip(GameObject& otherObject); virtual void hitSpaceStation(GameObject& otherObject); virtual void hitAsteroid(GameObject& otherobject); //...private: typedef void (Asteroid::*HitFunctionPtr)(GameObject& what); static HitFunctionPtr lookup(GameObject& what); typedef map< string, HitFunctionPtr > HitMap; static HitMap* initializeCollisionMap();};//The class SpaceShip Definitionvoid SpaceShip::collide(GameObject& otherObject){ HitFunctionPtr hfp = lookup(otherObject); //查找要调用的函数 if(hfp) { (this->*hfp)(otherObject); } else { throw CollisionWithUnknownObject(); }}SpaceShip::HitFunctionPtrSpaceShip::lookup(GameObject& what){ //不好,会有付出拷贝赋值的代价 //static HitMap collisionMap = initializeCollisioniMap(); //用一个Smart Pointer static auto_ptr collisionMap(initializeCollisionMap()); HitMap::iterator mapEntry = collisionMap->find(typeid(what).name()); // 如果查找失败,mapEntry == collisionMap.end(); if(mapEntry == collisionMap->end()) return 0; // 如果找到了,mapEntry会指向一个完全的map入口, // 它是一个(string, HitFunctionPtr)对。我们只想要 // 它的第二部分,所以这是我们返回的 return (*mapEntry).second;}SpaceShip::HitMap* SpaceShip::initializeCollisionMap(){ HitMap *phm = new HitMap; //这里书中直接就是(*phm["SpaceShip"] = &hitSpaceShip; //而我用的是Dev-C++编译器,结果我发现 // typeid(SpaceShip).name()并不仅仅是SpaceShip,而是128SpaceShip // 所以我做了如下修改 (*phm)[typeid(SpaceShip).name()] = &SpaceShip::hitSpaceShip; (*phm)[typeid(SpaceStation).name()] = &SpaceShip::hitSpaceStation; (*phm)[typeid(Asteroid).name()] = &SpaceShip::hitAsteroid; return phm;}void SpaceShip::hitSpaceShip(GameObject& spaceShip){ SpaceShip& otherShip = dynamic_cast(spaceShip); std::cout << "SpaceShip collide with SpaceShip" << std::endl;}void SpaceShip::hitSpaceStation(GameObject& spaceStation){ SpaceStation& station = dynamic_cast(spaceStation); std::cout << "SpaceShip collide with SpaceStation" << std::endl;}void SpaceShip::hitAsteroid(GameObject& asteroid){ Asteroid& theAsteroid = dynamic_cast(asteroid); std::cout << "SpaceShip collide with Asteroid" << std::endl;}//The class SpaceStation Definitionvoid SpaceStation::collide(GameObject& otherObject){ HitFunctionPtr hfp = lookup(otherObject); if(hfp) { (this->*hfp)(otherObject); } else { throw CollisionWithUnknownObject(); }}SpaceStation::HitFunctionPtr SpaceStation::lookup(GameObject& what){ static auto_ptr collisionMap(initializeCollisionMap()); HitMap::iterator mapEntry = collisionMap->find(typeid(what).name()); if(mapEntry != collisionMap->end()) return (*mapEntry).second;}SpaceStation::HitMap*SpaceStation::initializeCollisionMap(){ HitMap * pfm = new HitMap; (*pfm)[typeid(SpaceShip).name()] = &SpaceStation::hitSpaceShip; (*pfm)[typeid(SpaceStation).name()] = &SpaceStation::hitSpaceStation; (*pfm)[typeid(Asteroid).name()] = &SpaceStation::hitAsteroid; return pfm;}void SpaceStation::hitSpaceShip(GameObject& otherObject){ SpaceShip& ship = dynamic_cast (otherObject); std::cout << "SpaceStation collide with SpaceShip" << std::endl;}void SpaceStation::hitSpaceStation(GameObject& otherObject){ SpaceStation& otherSpaceStation = dynamic_cast (otherObject); std::cout << "SpaceStation collide with SpaceStation" << std::endl;}void SpaceStation::hitAsteroid(GameObject& otherObject){ Asteroid& theAsteroid = dynamic_cast (otherObject); std::cout << "SpaceStation collide with Asteroid" << std::endl;}//The class Asteroid Definitionvoid Asteroid::collide(GameObject& otherObject){ HitFunctionPtr hfp = lookup(otherObject); if(hfp) { (this->*hfp)(otherObject); } else { throw CollisionWithUnknownObject(); }}Asteroid::HitFunctionPtr Asteroid::lookup(GameObject& what){ static auto_ptr< HitMap > collisionMap(initializeCollisionMap()); HitMap::iterator mapEntry = collisionMap->find(typeid(what).name()); if(mapEntry != collisionMap->end()) return (*mapEntry).second;}Asteroid::HitMap* Asteroid::initializeCollisionMap(){ HitMap *pfm = new HitMap; (*pfm)[typeid(SpaceShip).name()] = &Asteroid::hitSpaceShip; (*pfm)[typeid(SpaceStation).name()] = &Asteroid::hitSpaceStation; (*pfm)[typeid(Asteroid).name()] = &Asteroid::hitAsteroid; return pfm;}void Asteroid::hitSpaceShip(GameObject& otherObject){ SpaceShip & ship = dynamic_cast (otherObject); std::cout << "Asteroid collide with SpaceShip" << std::endl;}void Asteroid::hitSpaceStation(GameObject& otherObject){ SpaceStation & station = dynamic_cast (otherObject); std::cout << "Asteroid collide with SpaceStation" << std::endl;}void Asteroid::hitAsteroid(GameObject& otherObject){ Asteroid & otherAsteroid = dynamic_cast (otherObject); std::cout << "Asteroid collide with Asteroid" << std::endl;}int main(){ GameObject *g = new SpaceShip; GameObject *h = new SpaceStation ; GameObject *a = new Asteroid; g->collide(*a); g->collide(*h); h->collide(*g); h->collide(*a); a->collide(*g); a->collide(*h);system("pause");} 该程序在winXP Professinal + Dev-C++上通过我在vc.net上也进行了编译,可是总是在dynamic_cast 处出现错误,不知道为什么?