#include <iostream>
/*
>如果宇宙飞船以低速与太空站碰撞,宇宙飞船会泊进太空站(程序没有涉及)
否则宇宙飞船和太空站受到的损害与其速度成正比
>如果宇宙飞船与宇宙飞船碰撞,或是太空站与太空站碰撞,都会受损,受到的损害与其速度成正比
>如果小号的小行星与宇宙飞船或太空站相撞,小行星会损毁。如果碰到的是大号小行星,
那宇宙飞船或太空站损毁
>如果小行星撞击另一颗小行星,两者都碎裂成更小的小行星,且想四面八方散去
*/
class GameObject{ ... };
class SpaceShip : public GameObject{... };
class SpaceStation : public GameObject{... };
class Asteroid : public GameObject{... };
void checkForCollision(GameObject&, GameObject&)
{
if(theyJustCollision(lhs, rhs))
processCollision(lhs, rhs)
else
...
}//
//virtual fcn + RTTI
// if_then_else way
class GameObject{
virtual void collide(GameObject& otherObject) = 0;
};
class SpaceShip : public GameObject{... };
class SpaceStation : public GameObject{... };
class Asteroid : public GameObject{... };
class CollisionWithUnKnowObject{//except class
public:
CollisionWithUnKnowObject(GameObject& whatWeHit);//why?
}
void SpaceShip::collide(GameObject& otherObject)
{
const type_info& objectType = typeid(otherObject);//lookup typeid & type_info
if(objectType == typeid(SpaceShip))
SpaceShip& ss = static_cast<SpaceShip&>(otherObject);
process a SpaceShip-SpaceShip collision;
else if (objectType == typeid(SpaceStation))//--copy
SpaceShip& ss = static_cast<SpaceStation&>(otherObject);
process a SpaceShip-SpaceStation collision;
else if (objectType == typeid(Asteroid))
SpaceShip& ss = static_cast<Asteroid&>(otherObject);
process a SpaceShip-Asteroid collision;//copy end
else
throw CollisionWithUnKnowObject(otherObject);
};
/*
*/
/
//overload只用虚函数,有图1
class GameObject{
public:
virtual void collide(GameObject& otherObject) = 0;
virtual void collide(SpaceShip& otherObject) = 0;
virtual void collide(SpaceStation& otherObject) = 0;
virtual void collide(Asteroid& otherObject) = 0;
};
class SpaceShip : public GameObject{
public:
virtual void collide(GameObject& otherObject) ;
virtual void collide(SpaceShip& otherObject) ;
virtual void collide(SpaceStation& otherObject) ;
virtual void collide(Asteroid& otherObject) ;
};
//impoint point:
virtual void collide(GameObject& otherObject)
{
otherObject.collide(*this);
}
//
class SpaceStation : public GameObject{... };
class Asteroid : public GameObject{... };
//
// virtual FCN Tables way
class GameObject{
public:
virtual void collide(GameObject& otherObject) ;
virtual void hitSpaceShip(SpaceShip& otherObject) ;
virtual void hitSpaceStation(SpaceStation& otherObject) ;
virtual void hitAsteroid(Asteroid& otherObject) ;
};
class SpaceShip : public GameObject{
private://!!
typedef void (SpaceShip::*HitFCNPtr)(GameObject&);//!!
static HitFCNPtr lookup(const GameObject& whatWeHit);
};
void SpaceShip::collide(GameObject& otherObject)
{
HitFCNPtr hfp = lookup(otherObject);
if(hfp)
{ this->*hfp}(otherObject);
else
throw CollisionWithUnKnowObject(otherObject);
}
class SpaceShip : public GameObject{
private:
typedef void (SpaceShip::*HitFCNPtr)(GameObject&);
typedef map<string, HitFCNPtr> HitMap;
};
void SpaceShip::lookup()
{
static HitMap collisionMap;//static in fcn !!
//init
collisionMap["SpaceShip"] = &hitSpaceShip;
collisionMap["SpaceStation"] = &hitSpaceStation;
collisionMap["Asteroid"] = &hitAsteroid;//error
HitMap::iterator mapEntry =
collisionMap.find(typeid(wharWeWait).name())//typeid::name
if(mapEntry == collision.end())
return 0;
return (*mapEntry).second;
}
//make init be smart ptr
//虽然只是为了调用时初始化,但好像简便了许多
class SpaceShip : public GameObject{
private://!!
static HitMap * initCollisionMap();
};
SpaceShip::HitFCNPtr
SpaceShip::lookup(const GameObject& otherObject)
{
static auto_ptr<HitMap>
collisionMap(initCollisionMap() );
}
SpaceShip::HitMap * SpaceShip::initCollisionMap()
{
HitMap* phm = new HitMap;
(*phm)["SpaceShip"] = &hitSpaceShip;
(*phm)["SpaceStation"] = &hitSpaceStation;
(*phm)["Asteroid"] = &hitAsteroid;
return phm;
}
//但上面的会出错,因为map的元素:函数指针的类型不一样
//因参数类型不一样。也不符合声明
SpaceShip::HitMap * SpaceShip::initCollisionMap()
{
HitMap * phm = new HitMap;
(*phm)["SpaceShip"] =
reinterpret_cast<HitFCNPtr>(&hitSpaceShip);
(*phm)["SpaceStation"] =
reinterpret_cast<HitFCNPtr>(&hitSpaceStation);
(*phm)["Asteroid"] =
reinterpret_cast<HitFCNPtr>(&hitAsteroid);
return phm;
}
//图2
//所谓reinterpret_cast 能不用就不用,解决办法是
class SpaceShip : public GameObject{
public:
virtual void collide(GameObject& otherObject) ;
virtual void hitSpaceShip(GameObject& otherObject) ;
virtual void hitSpaceStation(GameObject& otherObject) ;
virtual void hitAsteroid(GameObject& otherObject) ;
/*参数类型一致了*/
};
/*夹带真是性,我觉得我这一步有些多余,但为了消除使用者困惑*/
void SpaceShip::hitSpaceShip(GameObject& spaceShip)
{
SpaceShip& otherShip
= dynamic_cast<SpaceShip&>(spaceShip);
process a SpaceShip-SpaceShip collision;
}
void SpaceShip::hitSpaceStation(GameObject& spaceStation){...}
void SpaceShip::hitAsteroid(GameObject& asteroid){...}
//use non_member fcn to process a collision fcn
#include "SpaceShip.h"
#include "spaceStation"
#include "Asteroid"
namespace{
void shipAsteroid(GameObject& spaceShip,GameObject &asteroid);
void shipStation(GameObject& spaceShip,GameObject &spaceStation);
void StationAsteroid(GameObject& spaceStation,GameObject &asteroid);
void Asteroidship(GameObject& asteroid,GameObject &spaceShip)
{
shipAsteroid(asteroid,spaceShip);//就是如果参数相反,就调用上面的函数
}
//...都一样
};
item31让函数根据一个以上的对象类型来决定如何虚化
最新推荐文章于 2024-02-18 17:40:59 发布