Take the 2-minute tour ×

I know about the existence of static_cast, dynamic_cast. But I can't seem to find out a concrete reason to convince myself about why cast from base to derive or vice versa?

Any example in code would be appreciated.


class Base
        void foo();
        int _x;

class Derive: Base


Base *b = new Derive;  //will b behave the same as if it's a Derive *?
Derive *d = new Base;  //I think d can't behave like a Derive * but Base *, right?
share|improve this question
For a well-thought design, the use of casts is minimal, if not 0. –  Luchian Grigore Mar 31 '12 at 12:19
b will behave as a Derive * in the sense that if you add a virtual member function to Base and override it in Derive the latter would be called when you do b->f(). The definition for d will give you a compile time error. –  Nicola Musatti Mar 31 '12 at 12:40
@NicolaMusatti, why compile error? –  Alcott Mar 31 '12 at 12:45
You cannot assign a pointer to a base class to a pointer of a derived class. What would happen if you tried to access one of Derive's members from d? Base objects do not have them. –  Nicola Musatti Mar 31 '12 at 12:49
@MrLister I doubt any library expecting a void* is well-thought in terms of design. :) –  Luchian Grigore Mar 31 '12 at 12:56
show 2 more comments

3 Answers

up vote 2 down vote accepted

Actually, those casts are obvious marks of something unsual going on in the code, so in a perfect world, you shouldn't use them.

But in some cases they are the right tool for the job.

For static_cast, there are basically 2 cases:

1. Primitive conversion.

When you really need some integer number to be processed in a calculus involving floats.

float ratio = static_cast<float>( pixel_pos.x ) / static_cast<float>( pixel_pos.y ); // x and y are integers because pixel positions are absolute, but we need to get a floating point value here

2. You got an object from some external API and you want to get the specific child-type.

Thing* thing = factory.create( "shoe" ); // Even if I don't have it's real type, I know it's a shoe!

Shoe* shoe = static_cast<Shoe*>( thing ); // I need to use Shoe interface so lets cast it.

If you designed the system, maybe you could have done it better to avoid the cast. But if you didn't and the API you're using provide the base type as a way for you to work with it, then you don't have any other choice than to cast.

static_cast is useful also because it lets you assume something at compile time, so you should use it first because it requires you to be sure about what you are doing.

3.You don't know what is the real type of the object.

However, there is a specific case when you need to know the real type at runtime because there is no way for you to know it at another time. Typical case is when you're receiving some kind of objects from an external system and there is no other information about the real type of the object

void on_something_happen( const Event& event ) // callback triggered when an event occured in the library system this callback is plugged in
     // here I want to manage two cases
     ThingEvent* thing_event = dynamic_cast<ThingEvent*>( &event );

    if( thing_event )
        // do my thing

        // ok this event HAVE TO be a FooEvent, otherwise this should crash
        FooEvent& foo_event = dynamic_cast<FooEvent&>( event );
        // do my thing


share|improve this answer
So if the dynamic_cast fails, it returns 0. Then when will it fail? –  Alcott Mar 31 '12 at 12:54
It returns nullptr (or 0 with C++03 compilers) if it fails when casting a pointer, it throws an exception if you're casting a reference. You should try to know more about when to use which cast. Also know that dynamic_cast have a cost at runtime that is important to know, both on time and memory, because it adds RTTI. –  Klaim Mar 31 '12 at 13:01
Actually it returns neither 0 nor nullptr but a null pointer of the correct pointer type (the same value 0 or nullptr gives when converted to that poiter type). –  celtschk Mar 31 '12 at 13:11
For the situation shown for case 1, I would not use static_cast but add 0.0 or multiply with 1.0. For example, (1.0*x)/y. –  celtschk Mar 31 '12 at 13:15
Also, the dynamic_cast to reference will not crash, but throw an exception if the type is wrong. –  celtschk Mar 31 '12 at 13:18
show 2 more comments

suppose you have:

struct A {
  int i;

struct B : A {
  char c;

struct C : A {
  double d;

And some function f() returning a pointer to A, for which you don't know the definition. When you do:

A * a = f();

How do you know what you can do with a? According to the definition above every B and C is also an A, so you know that if a is not null you can use its i data member without problems. On the other hand, in order to use either c or d you need to know the actual type of a, and that is achieved with dynamic_cast.

Let's suppose you know that a is actually a pointer to B. What you can do is:

if ( b != 0 )
  b->c = 'd';

(Yes, I know we assumed you know it, but such assumptions never hold forever...)

share|improve this answer
If the actual type of a isn't A* but B*, then I can use a as if it's a pointer to B object? –  Alcott Mar 31 '12 at 12:29
You need a cast. I'll update my answer to provide an example. –  Nicola Musatti Mar 31 '12 at 12:32
If a is not a pointer to B but C, then dynamic_cast will fail? –  Alcott Mar 31 '12 at 12:44
It will return 0 when called on a pointer and raise an exception when called on a reference. –  Nicola Musatti Mar 31 '12 at 12:46
Performing the initialization in the if is more idiomatic- if (B* b = dynamic_cast<B*>(a)) { .. } –  Puppy Mar 31 '12 at 12:50
show 2 more comments

The typical situation is the need to add an operation to an existing data type, but you can't add it directly.

Suppose you have this class structure:

struct Base {
  virtual doSomething() = 0;

struct Derived1 : Base {
  virtual doSomething();
  int x,y;

struct Derived2 : Base {
  virtual doSomething();
  float a,b;

Now you are writing a function that is passed a Base&:

void f(Base& base);

You want to be able to print information about base, but for whatever reason, you aren't allowed to modify Base to add this operation (it is part of a commercial library, for example). In that case you may have to do something like this:

void f(Base& base)
  if (Derived1* p=dynamic_cast<Derived1*>(&base)) {
    cout << "Derived1{" << p->x << "," << p->y << "}\n";
  else if (Derived2* p=dynamic_cast<Derived2*>(&base)) {
    cout << "Derived2{" << p->a << "," << p->b << "}\n";
  else {
    cout << "Unknown type\n";

This is typically considered bad style in an object-oriented language though. One problem is that if you add a new class to your hierarchy, then the compiler won't help you find the places where you need to add code to handle operations on instances of that new class.

share|improve this answer
I'd go with a facade/adapter/whatever this is called instead of a string of if(dynamic_cast) else if (dynamic_cast) ... . There are cases for dynamic casts, but never for linear sequences of casts. –  Alexandre C. Mar 31 '12 at 12:56
So if the passed in Base & base is actually a reference to a Derived1 or Derived2 object, then the dynamic_cast will succeed, but if base is a reference to a Base object, then dynamic_cast will return 0? –  Alcott Mar 31 '12 at 12:58
@Alcott: Since Base is abstract, there cannot be any Base object which isn't of a dynamic type derived from Base. –  celtschk Mar 31 '12 at 13:06
add comment

Your Answer


