views:

83

answers:

3

Let me start with a concrete example. In C++, I have a hierarchy of classes under the abstract base class CollisionVolume. Any collision volume needs to be able to detectCollision with any other volume. This collision code is specialized based on the two subclasses in presence, but it is commutative: detectCollision(a, b) == detectCollision(b, a).

I need to use a mechanism similar to virtual functions since the objects will typically be of the abstract base class. However, if I use typical virtual methods, the chosen function can only depend on the type of one of the operand, not both. The only way I was able to do this is using RTTI or an RTTI-like mechanism.

Is there any cleaner way to do this?

+2  A: 

You're looking for multiple dispatch. C++ doesn't have it because it's hard to implement efficiently. Most other statically typed/efficiency-oriented languages don't either. Your RTTI solution is probably about the best way of faking it.

dsimcha
The Wikipedia page for "multiple dispatch" even uses collisions in the example section - too funny. (I'm not a game programmer, maybe that is *the* canonical example of its usage...)
Dan
Strange. I stumbled upon a link to multiple dispatch a couple of days ago but didn't follow it. Thanks a lot!
Philippe Beaudoin
+1  A: 

There are several solutions to emulate multimethods in C++.

Here some references that can helps you to solve your problem:

S.Meyers "More effective C++", Item 31: Making functions virtual with respect to more than one object.

A.Alexandrescu "Modern C++ design", Chapter 11. Multimethods

MultiMethods in C++: Finding a complete solution by Danil Shopyrin

Multiple Dispatch. A new approach using templates and RTTI by Dr. Carlo Pescio, C++ Report, June 1998.

Draft proposal for adding Multimethods to C++, here and here

Sergey Teplyakov
Great links! Thanks!
Philippe Beaudoin
A: 

My initial idea, which upon reading appears to be the visitor pattern(?), is to make a virtual function that returns some vital information about the object, then, in detectCollision(), compare the vital information returned by the two objects. That way, each object can return specialized information, but they can be compared in a generalized way.

This may not be the most efficient way of doing it, but it seems relatively simple.

Chris Lutz
I've thought about the visitor pattern but it doesn't quite work.The collision detection code can be quite specialized based on the two volumes in presence. The "vital information" would therefore be used to branch between different execution path. This is roughly what I do with my RTTI-like solution: query the type and branch based on it.
Philippe Beaudoin