Alternatives To dynamic_cast

Yeah it’s best to avoid dynamic_cast as much as possible. Ask yourself what you want to do with those planes, here is a few ideas:

  1. You could use a separate list of Plane, and make the Plane themselves register or unregister inside this list. Why matter with those Peasants where you can directly talk to their Bosses?
  • Things is you have to maintain this separate list, and you need a system to make the Planes register themselves in that list. And unregister when they’re removed from the game!
  1. If you only ever deal with a lone Plane, well, just keep it as a pointer somewhere and use it directly!
  • The most efficient of all, except you can only have one Plane of course.
  1. You could use a generic signal system, based on something like virtual void sendSignal(unsigned signalCode). Only Batman answers to the Bat-Signal, right? You can do the same with Planes. Plus you get to reuse this system for other stuff, like a self-destruct (game-wise) button for some secret base (e.g. sendSignal(SECRET_DESTRUCTION_SIGNAL)).
  • That means you have to get some method void dispatchSignal(unsigned signalCode) that will dispatches it to every active GameObj.
  • You can combine it with #1, with a list per signal-code. Thus, no useless sendSignal calls, and Planes aren’t going to receive the Bat-Signal this way and Batman won’t receive the SECRET_DESTRUCTION_SIGNAL. Or maybe he will, because he might have someone left to rescue?
  • You could use type for the signal of course. unsigned are just generic, but a struct enum could provide additional checks and restrictions!
  1. You could also use something more polluting: a method virtual Plane* asAPlane() that, for Planes and Plane-Derived, gives you *this, and nullptr for the rest of GameObjs.
  • It’s polluting because if you need to do that for more than one class, you’re going to have a lot of those “casting” methods.
  • You’ll end up having to check every active GameObj too. If you got a lot of Plane, that’s probably OK. If you only have 1 for 100 GameObjs, you’re going to do 99 checks for nothing.

All of those are much quicker than a dynamic cast and none requires the RTTI.

In regards to number 1:
If it really is suitable then yes.
XNA uses this to group updateables and drawables into their own lists.

In regards to number 2:

  • prefer references over pointers because it’s less effor to change the syntax when switching between value and reference and because references can’t be nullptr.
  • prefer to pass a reference to the plane to functions rather than referring to it as a global variable. That way if you ever need any more planes (e.g. you add multiplayer) then you usually only have to rewrite the code that passes the planes in to the functions, instead of doing a massive overhaul.

In regards to number 3:

If you do end up doing that, please use an enum class instead of a plain integer and defines.
It’s a lot harder to mess up because it’s typesafe and it’s more self-documenting.

e.g.

enum class Signal
{
  Activate,
  Deactivate,
  Fire,
};

class GameObject
{
public:
  virtual void sendSignal(Signal signal) = 0;
  // etc
}

This has the added benefit that you can’t do this:

GameObject * object = getObject();
object->sendSignal(84368); // Is this valid? I have no clue, but it compiles anyway

With an enum class :

GameObject * object = getObject();
object->sendSignal(Signal::Fire); // It's a valid Signal, thus this is valid
object->sendSignal(Signal::Quack); // Compiler error, no such signal

And as for number 4
That’s going to get really awkward really quickly so I’d avoid that at all costs.

The visitor pattern is probably a much better solution, even though it’s a little hard to get right on C++ because of the complexity of C++'s rules.

I suddenly realised I wasn’t aware of any good C++ examples of the visitor pattern, so I just wrote one:

As you can see, the magic is that the visitor object gets to decide how to react to the specific type of the object. This can be very useful, especially for processing tree-like structures.

This is known as ‘double dispatch’, while lone virtual methods employ what’s called ‘single dispatch’. Both are an example of dynamic dispatch.

There’s a rudimentary example of using double dispatch for complex collision detection on wikipedia.

Ultimately I’d still warn against this if a better system can be found.


Another option would be to switch to a component system.

Again, they’re kind of difficult to understand and get working, but they’re very flexible.

Basically the idea is that instead of making one class per thing, you make one class per type of behaviour and stuff a bunch of them in a container. For example, instead of having a Plane, you’d have a container containing a MovementComponent, a DrawingComponent, an InputComponent and maybe a PhysicsComponent.

Some really good examples describing the Component pattern:

This one is long, but game programming patterns by Bob Nystrom is pure gold:
http://gameprogrammingpatterns.com/component.html

This one is perhaps less useful because it’s for Elixir, not C++, but it’s full of illustrative diagrams and fluffy bunnies:

(There used to be a really good article about component systems somewhere but I think the website got shut down and I can’t remember what it was called.)

2 Likes

That’s sound nice, deserve some in depth analysis.

It’s where I started from but I then I change my mind midway to a more object oriented with classic inheritance.

Already on my radar

Thanks! Clean and interesting way to structure a program.


Thanks all for suggestions.
It would be really nice in future to read some in deep tutorial on programming patterns. Maybe a mid size game that take advantages of a well structured software.

1 Like

I have to agree, this book is pure gold!! And very interesting too :smiley:

Entity Component System might be a bit too heavy for the ram we got in the pokitto thought, but maybe I’m wrong. I feel like one class per entity is better for the pokitto?

Double dispatch is indeed very nice to detect collisions between shapes, but is also great for anything of various forms that can interact with each other, as long as you don’t have too many forms - 1 form gives you 1 method, 2 gives you 3, 3 gives you 6, 4 gives you 6 … (not counting the duplicate methods that gets the same parameters but reversed).

1 Like

Possibly, it depends how flexible you make it.

If it was limited to a fixed number of possible components then it might not be too bad. E.g. if you only had drawing, physics, sound and maybe a few bits of game logic then it could be kept smallish.

It’s surprising how little space something will use if you’re careful with how you use memory. Techniques like flyweights and pooling can really help to keep the cost down.

Also, compared to what I’m used to with the Arduboy (2KB, ~half of which is eaten by the library), the Pokitto’s 36KB feels massive.

Every pattern is a double-edged sword somehow.
The key is to make sure the positives outweigh the negatives.

The only system I can imagine needing lots of different ‘forms’ is an expression tree/parse tree. Most other things will usually have an alternative (e.g. using an enum class as a type identifier).

Actually, while I think of it, would anyone mind if I split everything from here onwards into a separate thread called “Alternatives to dynamic_cast?”.

We’ve got kind of far away from the original topic and it would be a shame for this discussion to be buried at the bottom of an unrelated thread, I think it deserves its own.

1 Like