News:

This week IPhone 15 Pro winner is karn
You can be too a winner! Become the top poster of the week and win valuable prizes.  More details are You are not allowed to view links. Register or Login 

Main Menu

C++ tips - Thoughts on multiple dispatching

Started by ben2ong2, October 07, 2006, 09:50:15 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

ben2ong2

[JC] = You are not allowed to view links. Register or Login (John Cooper), Vivid Technologies Inc., 5 Aug 93

   I was wondering what the current thinking is on good approaches to
multiple dispatching in C++ programs. I was thinking of something along
these lines, but I'm interested in hearing what more experienced programmers
think:

[JS] = You are not allowed to view links. Register or Login (John Max Skaller)

   Use a switch. There isn't any other way. Not because of some
deficiency of C++, but because its theoretically absurd. Only
single dispatch can be implemented by vectoring (indirect function call),
which is the key to object oriented techniques in static systems like C++.

[JC]

   Suppose I am writing a game that is a variant of chess in which only
certain pieces are allowed to capture certain other pieces. When a piece is
moved (say with a mouse) on the board and a player wishes to attempt a
capture, I'd like the program to do some sort of highlighting if the capture
is allowed between those two pieces.

   I had something like this in mind:

   o A base class PlayingPiece from which all the other pieces are derived.
   o Derived classes King, Queen, Bishop, Knight, Rook, Pawn.
   o Virtual functions DispatchCapture and Capture.

[JS]
   Why bother. Just write out all the cases. It wrong to use
a virtual function to handle a finite set of fixed alternatives:
thats what a switch is for.

[JC]

Example:

   void HandleCapture(PlayingPiece *attacker, PlayingPiece *defender)
   {
      :
      // Dispatch polymorphically on defender's actual type.
      defender->DispatchCapture(attacker);
      :
   }

Every derived class would have its own DispatchCapture member function:

   void King::DispatchCapture(PlayingPiece *attacker)
   {
      // Call Capture polymorphically on attacker's actual type. Which
      // overloaded Capture function gets called is based on the actual
      // type of "this".
      attacker->Capture(this);
   }

   etc.

Each derived class would override Capture as necessary:

   void King::Capture(King *defender)
   {
      /* Do whatever */
   }

   void King::Capture(Queen *defender)
   {
      /* Do whatever */
   }

   etc.

Is this a canonical technique for realizing simple multiple dispatch?

[JS]

   IMHO: this is a canonical abuse of inheritance.
And it cant possibly work :-)

Think of it this way: virtual functions implement operations
on *arbitrary* types. But a 'capture' function depends on
both the capturing and captured object piece.

For a given piece, say a Queen, there is *no way* you can possibly
specify arbitrary capturing rules in finite code. You might
specify it if you made the rules non-arbitrary, for example,
if you rated every piece with a number, and just allowed
pieces with higher ratings to capture those with lower ratings.

So: if you cant make a generalised rule that covers arbitrary
pieces, not yet dreamed up, then you should not use polymorphism
at all .. because you cant do so without violating the basic
principles which enable it in the first place: the open closed
principle.

Note: I like the example of chess pieces. Its clear that
using a common base class Piece is useful for things
like drawing the pieces. So a 'draw' routine is a good candidate
to be a pure virtual in 'Piece': this is a good place to
use polymorphism.

Note that 'draw' is a *property* of the Piece. Capture, on
the other hand is a relation. Polymorphism doesnt work with
relations. (with a couple of exceptions, as I learned
when someone gave an example that worked)

You are not allowed to view links. Register or Login
You are not allowed to view links. Register or Login