4

I'd like to know when dynamic_cast must or should be used over static_cast, with examples. I've read this SO question, but it doesn't really provide any concrete examples. I am assuming most examples will involve polymorphic class types. Currently the only reason I know to use dynamic_cast over static_cast is if I am not 100% sure of the concrete type I am working with.

Some other thoughts:

  • Casting sideways (in multiple inheritance)
  • Casting up to a base class in a virtual inheritance hierarchy
  • Will the pointer change (if using static_cast) when casting to the "right most" inherited types in a class that uses multiple inheritance?

Is the "if the type is not known" reason the only reason? If not, could someone provide examples that demonstrate why dynamic_cast must or should be used over static_cast?

Community
  • 1
  • 1
void.pointer
  • 24,859
  • 31
  • 132
  • 243
  • 1
    AFAIK `dynamic_cast` is _only_ for casting from base to derived, and the base _must_ have at least one virtual function. In almost all other circumstances, you want `static_cast` – Mooing Duck Oct 01 '12 at 16:39

2 Answers2

2

In general, you should use dynamic_cast when converting within a hierarchy, regardless. One possible exception is when converting from a derived class to a base (pointers or references, of course). Otherwise, about the only time you'd use static_cast within a hierarchy is when the profilers says you must.

static_cast is more often used when converting to or from a void*, or to ensure the correct type of a null pointer constant, or for conversions which don't involve pointers or references (e.g. static_cast<double>( someInt )).

James Kanze
  • 150,581
  • 18
  • 184
  • 329
  • "static_cast is more often used when converting to or from a void*" -- although `dynamic_cast` has its own meaning. So it's not so much the fact that you're casting to `void*` that dictates which cast to use, as what you want the result to be. – Steve Jessop Oct 01 '12 at 16:38
  • 1
    How can static_cast verify the validity of a cast from `void*` to some other type? `void*` has no static type information (other than it is a pointer). – void.pointer Oct 01 '12 at 16:39
  • @SteveJessop Can you explain the differences? – void.pointer Oct 01 '12 at 16:40
  • @RobertDailey: it doesn't verify the validity, other than the slightly-above-the-level-of-syntax rule that all casts between `void*` and any pointer-to-object type are valid. And the difference between `static_cast` and `dynamic_cast` is that when applied to a pointer-to-base-class in a polymorphic hierarchy, the former returns the same address as you pass in, whereas the latter returns the address of the most-derived object of which you have a pointer to a base class. It's rarely useful, but there it is... – Steve Jessop Oct 01 '12 at 16:41
  • "it" being static_cast, and yes I'm saying that. One of the purposes of `static_cast` is that it can reverse any implicit conversion. There is an implicit conversion from `MyClass*` to `void*`, and a `static_cast` back from `void*` to `MyClass*`. – Steve Jessop Oct 01 '12 at 16:46
  • @SteveJessop I was referring to a cast *from* void, like such: `static_cast( myVoidPointerVariable )`. You said "to/from", and AFAIK this won't compile (reinterpret_cast is mandatory). Am I misunderstanding? (Sorry I phrased my last comment incorrectly and removed it) – void.pointer Oct 01 '12 at 16:46
  • `reinterpret_cast` is not mandatory. I don't recommend it for that purpose, because there are types that you can `reinterpret_cast` to `MyClass*` but cannot `static_cast`, such as `int`. Using a `static_cast` gives you the minimal type-safety of checking that the source isn't one of those. – Steve Jessop Oct 01 '12 at 16:48
  • @SteveJessop When converting to a `void*`, yes, although I don't think I've ever wanted the semantics of `dynamic_cast` here; in fact, it's one case where I've often used a `static_cast` to a base class (e.g. when passing the `arg` argument to `pthread_create`). Otherwise, I've used it almost exclusively with legacy interfaces, which for various reasons return or output `void*` of known type. – James Kanze Oct 01 '12 at 16:51
0

One situation where you must use dynamic_cast even though you know the dynamic type is when cast­ing from a virtual base to a more-derived type:

struct A { };
struct B : virtual A { };
struct C : virtual A { };
struct D : B, C { };

A * p = new D;
D * q = dynamic_cast<D*>(p);

The reason is of course that the virtual base is only determined at runtime.

Another use of dynamic_cast is to discover the address of the most-derived object by casting to void*, though it's not entirely clear whether that's a necessary language feature. (I managed to con­trive a use case, but it's mostly academic.)

Community
  • 1
  • 1
Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084