10

I am reading the book, "A Tour of C++", and cannot understand following paragraph. What does "a different type is unacceptable" mean? So, when to use pointer casting and when to use reference casting? Can somebody elaborate this? Thanks.

Edit: The other question, "Difference in behavior while using dynamic_cast with reference and pointers" is asking the behavior of dynamic_cast, which I could understand - return nullptr or throw exception. In this question, I am asking when to use one and when to use the other.

"We use dynamic_cast to a pointer type when a pointer to an object of a different derived class is a valid argument. We then test whether the result is nullptr. This test can often conveniently be placed in the initialization of a variable in a condition. When a different type is unacceptable, we can simply dynamic_cast to a reference type. If the object is not of the expected type, bad_cast is thrown:" - A Tour of C++, Section 4.5.3

Community
  • 1
  • 1
MaxHeap
  • 1,138
  • 2
  • 11
  • 20

2 Answers2

16

Basically if our object is allowed to be one of different types, we can dynamic_cast to a pointer so we can check if the cast succeeded:

void do_if_derived(Base& b) {
    Derived* d = dynamic_cast<Derived*>(&b);
    if (d) {
        // do something
    }
    else {
        // not a Derived, this is OK
    }
}

but if our object has to be a single specific type, we can dynamic_cast to a reference and let the cast throw if it happens to be wrong:

void this_better_be_a_derived(Base& b)
{
    Derived& d = dynamic_cast<Derived&>(b);
    // do stuff with d
    // will throw if, e.g. b is a DifferentDerived& instead
}

It's a matter of wanting to handle the failure case via a branch or via an exception.

Barry
  • 286,269
  • 29
  • 621
  • 977
5

"Unacceptable" just means "cannot be accepted" here. Specifically, by your own code.

You can use dynamic_cast<T*>(e) if your own code can handle the case where *e is not of type T, by checking the result of the conversion and doing something else if the conversion failed.

You can use dynamic_cast<T&>(e) if the execution of your own code cannot meaningfully continue if e is not of type T.