2

I have a class hierarchy as such:

Entity Stationary Tree Creature Bear Crow 

And I have a World and a Player. When the Player bumps into something it gets a call to handleCollision(Entity* entity) and then depending on what it is different things happen; if the player bumps into a tree nothing happens while the player attack if it's a bear. The problem is that I'm not sure how to differentiate between cases in a good way.

One thought that has come to mind is someting like this. Player::handleCollision(Entity*) calls Entity->handleCollisionHelper(Player& ). This is a virtual function which in Tree does nothing and in Creature(it should attack all creatures) calls Player.handleCollisionCreature(this) and then place the attack code in handleCollisionCreature. Is there a better way to do this without using RTTI (typeid etc)?

3
  • 1
    What you are doing is fine. It's called double-dispatch and is a common pattern in such cases. Commented Jan 11, 2010 at 11:02
  • I have no idea why everybody thinks this is double dispatch. We have only one object with a variable type (The object being collide with (an Entity)). The other side of the equation has an object of fixed type (a Player). Thus this is single dispatch, thus virtual functions are a perfect way to implement a solution. Commented Jan 11, 2010 at 15:33
  • Martin, A way to implement this using single dispatch only would require a method such as "CollidedWithPlayer()" in the Entity base class (and derived classes). This is possible, but fairly limited - what happens when you wish to suddenly start supporting collisions with other objects? Or when Player is also a base-class and may have different sub-classes with specific collisions? Depending on context, it may be a viable solution. Probably not in the context described here. Commented Jan 12, 2010 at 5:50

4 Answers 4

3

The virtual method with (Player& player) arg seems perfectly good OO design. As you said, you could add some form of type or use RTTI and switch case through the permutations but that would be very C style functional style. Just as long as you aren't making thousands of virtual calls per second you should be fine.

Sign up to request clarification or add additional context in comments.

Comments

2

Just to provide a reference for the official name - this problem is known as Double Dispatch (you need to decide what to do based on the type of two objects at the same time).

See the Wikipedia article http://en.wikipedia.org/wiki/Double_dispatch for some details, and a suggested solution.

1 Comment

Why does he need double dispatch. I only see one object that may have different types (the object being hit). On the other side the object doing the hitting is always a Player. Thus this is single dispatch as implemented via virtual functions.
0

Instead of triggering on Entity*, why don't you have something like this:

 handleCollision(Stationary& stationary) { // Nothing to do yet? } 

and

 handleCollision(Creature& creature) { creature.StartCombat(this); } 

And remove the Entity* function. This will ensure only creatures will start combat (Add StartComabt function to your Creature class). Alternately, you could have a Combat class:

 handleCollision(Creature& creature) { Combat::Begin(this, creature); } 

Comments

0

I think what you're looking for is called "double dispatch" or "multimethods".

Calling different functions depending on the dynamic type of more than one object is not a built-in feature of C++, but there are a number of well-known techniques to roll your own. Cascaded calls as you propose is probably the most common one.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.