4
votes

I don't figure out the real difference between static_cast and dynamic_cast in below scenario:

                                **///with static_cast///**
    class Foo{};
    class Bar: public Foo
    {
        public:
          void func()
          {
            return;
          }
    };

    int main(int argc, char** argv)
    {
        Foo* f = new Foo;
        Bar* b = static_cast<Bar*>(f);
        b->func();
        return 0;
    }

Output:

Successfully Build and Compiled!

                                **///with dynamic_cast///**
    class Foo{};
    class Bar: public Foo
    {
        public:
          void func()
          {
            return;
          }
    };

    int main(int argc, char** argv)
    {
        Foo* f = new Foo;
        Bar* b = dynamic_cast<Bar*>(f);
        b->func();
        return 0;
    }

Output:

main.cpp: In function 'int main(int, char**)': main.cpp:26:34: error: cannot dynamic_cast 'f' (of type 'class Foo*') to type 'class Bar*' (source type is not polymorphic) Bar* b = dynamic_cast(f);

I'd be appreciated if someone could help me understand this!

1
While the first builds and runs, it will lead to undefined behavior, because f (and therefore b) isn't a pointer to a Bar object.Some programmer dude
As for dynamic_cast, this reference should be helpful.Some programmer dude
You can't cast a pointer to a base class object to a derived class pointer. dynamic_cast (in case of virtual members) will return nullptr. static_cast will compile but using such pointer will result in undefined behavior.Daniel Langr
@DanielLangr Such cast itself is undefined behavior.xskxzr

1 Answers

6
votes

The hint is in the part

(source type is not polymorphic)

It means, for dynamic_cast to work, it needs a polymorphic base class, i.e. have a virtual method

class Foo {
public:
    virtual ~Foo() {}
};

Apart from that, it will not work, because f does not point to a Bar object. dynamic_cast will return a nullptr in this case, which you must check

Foo* f = new Foo;
Bar* b = dynamic_cast<Bar*>(f);
if (b != nullptr)
    b->func();