Sankalp
Sankalp

Reputation: 2824

Forced necessity of dynamic_cast operator in C++

dynamic_cast is generally used when we have a base class pointer and want to downcast it to a derived class. For instance,

class A
{
      public:
      virtual void foo();
};

class B : public A 
{
      public:
      void foo();
};

main()
{
    A* a = new B();
    B* b = dynamic_cast<B*> (a);
}

But, the same can also be accomplised by using C-style cast:

B* b = (B*)a;

So, my question is what are the circumstances/cases where it becomes completely necessary to use this operator i.e. there is no other choice?

Upvotes: 1

Views: 616

Answers (5)

microtherion
microtherion

Reputation: 4048

One situation in which a dynamic_cast returns a different (and correct) result is when you’re casting from a non-leftmost base class:

class A { 
public:
   int x; 
}

class B {
public:
   virtual void foo();
};

class C : public A, public B
{
     public:
     void foo();
};

main()
{
   B* b = new C();
   C* c = dynamic_cast<C*>(b);
}

A C-style cast would return an incorrect pointer here.

Upvotes: 0

Mike Vine
Mike Vine

Reputation: 9837

Adding to some of the answers above, even if you ignore the fact dynamic_cast is clever, using c style casts in c++ code as a replacement for static/const/reinterpret cast is really dangerous.

Depending on what is visible at the time of the cast [which can change if header files get removed for example], a c-style cast may not do pointer arithmetic correctly and leave you ending up with a garbage pointer.

You never want adding or removing header files to change the meaning of your code. C++ casts do not have this problem, if the compiler cannot work out what it should do you'll get a compilation failure, and not the random runtime crashes you may get with c style casts.

Upvotes: 1

Armen Tsirunyan
Armen Tsirunyan

Reputation: 132984

But, the same can also be accomplised by using C-style cast:

No, it cannot :)

By definition, The C-Style cast will try to perform a series of const_cast, static_cast, and reinterpret_cast1 to achieve your desired cast but not dynamic_cast. So, essentially, here C-style cast is equivalent to a static_cast which will have undefined behavior if the actual dynamic types won't match (conversely, in this situation the dynamic cast will return nullptr in case of pointers and throw std::bad_cast in case of references).

That is to say, if you're certain that you're casting to the right type, then use static_cast (or C-style cast, but I personaly don't like it). But if you are not certain, then use dynamic_cast

1 C-Style cast can be used to also cast to a private base, which can't be done with the aforementioned series of C++-Style casts

Upvotes: 4

utnapistim
utnapistim

Reputation: 27365

If your question is when you should use dynamic_cast over C-style cast, the answer is always (that is, if you have to choose between C-style cast and dynamic_cast, always prefer dynamic_cast).

In general though, strive to never use C-style casts in C++. They are difficult to locate by a tool (unless that tool is a compiler) and they lead to code that has to be read explicitly looking for casts whenever you refactor (sources of bugs).

If your question is when you should use dynamic_cast over designs that do not require it, the answer is almost never. Generally, you should avoid designs that require your implementation to downcast pointers or references. When your implementation forces you to down-cast, it is most often a sign of poor design (i.e. the correct solution is probably refactoring, not down-casting).

Upvotes: 2

Dialecticus
Dialecticus

Reputation: 16761

When you don't actually know that a points to object of type B dynamic_cast will return a null pointer, which you can check and handle the situation accordingly. With C-style cast you get a pointer, but when you try to use it undefined behavior happens.

Upvotes: 2

Related Questions