Shivaraj Bhat
Shivaraj Bhat

Reputation: 847

Can be upcast and downcast both done using dynamic_cast in C++

I was going through dynamic_cast concept in c++.

Say suppose we have a class Base and 2 derived classes class D1 and class D2 which are derived from Base. Class Base has a virtual function fun().

My questions are:

  1. Can upcast and downcast both be done with dynamic_cast?
  2. If yes, which one is more preferred and advantageous? In which cases we can go for downcast/upcast in this regard?
  3. Is any of the cast not recommended or harmful?

Please explain with the use cases for the same considering the above scenarios to get a more clear picture on this. Any clear explanation would be really helpful.

Upvotes: 3

Views: 7618

Answers (1)

Konrad Rudolph
Konrad Rudolph

Reputation: 545943

  1. Is upcast and downcast can both be done in dynamic_cast?

Upcasting with dynamic_cast makes no sense whatsoever. Upcasts will always succeed. dynamic_cast is used when you’re not certain whether a downcast will succeed, and you thus check the result of the cast for success.

Let’s say you have a function f which takes a B& and has to decide what kind of object it gets:

void f(B& b) {
    D1* d1 = dynamic_cast<D1*>(&b); // notice the address-of operator!
    if (d1 != nullptr)
        std::cout << "We got a D1!\n";
    else if (dynamic_cast<D2*>(&b) != nullptr) // No need to assign to a variable.
        std::cout << "We got a D2!\n";

    // Or, with a reference:
    try {
        D1& d1_ref = dynamic_cast<D1&>(b); // reference!
        std::cout << "We got a D1!\n";
    catch (std::bad_cast const&) {
        std::cout << "It was NOT a D1 after all\n";
    }
}

Importantly, all the above code operates on either pointers or references. This is what we need to do in C++ to deal with polymorphic objects. We cannot just use values here.

  1. If yes., Which one is more preferred and advantageous.? In which cases we can go for downcast/upcast in this regard?

In your case, we’d have:

D1 derived;
B& b = derived; // implicit upcast
b.fun();

static_cast<B&>(derived).fun(); // explicit upcast

// But actually, no upcast is of course needed to call `fun`:
derived.fun();

Upcast is implicit, you don’t need to use any cast for this. If you explicitly want to treat an object as a base class type, use a static_cast.

  1. Is any of the cast is not recommended or harmful?

See above. For further information, read the cppreference entry on dynamic_cast.

Upvotes: 9

Related Questions