Double-dispatching

xiaoxiao2021-03-18  249

1. The basic idea is Violence: Using Virtual Functions and RTTI following excerpt from "More Effective C " class GameObject {public: virtual void collide (GameObject & otherObject) = 0; ...}; class SpaceShip: public GameObject {public: Virtual Void Collide (GameObject & OtherObject); ...};

void SpaceShip :: collide (GameObject & otherObject) {const type_info & objectType = typeid (otherObject); if (objectType == typeid (SpaceShip)) {// exactly the same type of object typeid only as parent class and subclass not typeid as paceShip & ss = static_cast (otherObject); process a SpaceShip-SpaceShip collision;} else if (objectType == typeid (SpaceStation)) {SpaceStation & ss = static_cast (otherObject); process a SpaceShip-SpaceStation collision; } else if (objectType == typeid (Asteroid)) {Asteroid & a = static_cast (otherObject); process a SpaceShip-Asteroid collision;} else {throw CollisionWithUnknownObject (otherObject);}} for GameObject each subclass, are Write a similar code. This approach is more intuitive, but it is more dead. If you want to add a subclass of a new GameObject, you need to modify the Collide function of all the existing subclats of GameObject. And all of the subclasses of GameObject know all other subclasses of GameObject.

2. Only the code below the virtual function is taken from "More Effective C "

Class spaceship; // forward declarations

Class spachen;

Class asteroid;

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 Spaceeship: public gameObject {

PUBLIC:

Virtual Void Collide (GameObject & OtherObject);

Virtual Void Collide; Virtual Void Collide (SpacStation & OtherObject);

Virtual Void Collide (Asteroid & OtherObject);

...

}

Void Spaceeship :: Collide (GameObject & OtherObject)

{

OtherObject.collide (* this); // Key a call, because * this is known, otherobject.collide (* this) will call to the correct version of the overload function

}

Void Spaceeship :: Collide (SpaceShip & OtherObject)

{

Process a spaceship-spaceship collision;

}

Void Spaceeship :: Collide (SpaceStation & OtherObject)

{

PROCESS A SpaceShip-SpaceStation COLLISION;

}

Void SpaceShip :: Collide (Asteroid & OtherObject)

{

Process a spaceship-asseteroid collision;

}

This approach is smart than the violence, but the scalability is still not good. When adding new subclasses, you need to modify the interface of GameObject, increase the corresponding member function, and all existing subclasses need to be modified.

3. It is better than 1, 2, using similar MAP manufacturing functions.

转载请注明原文地址:https://www.9cbs.com/read-129902.html

New Post(0)