简体   繁体   中英

std::bad_cast pointer vs reference situation

I've noticed with regard to the std::bad_cast exception that references and pointers don't seem to act the same way. For example:

class A { public: ~A() {} };
class B : public A {};

//Case #1
int main()
{
    A a;
    B& b = dynamic_cast<B&>(a);  //Would throw std::bad_cast.
}

//Case #2
int main()
{
    A* a = new A;
    B* b = dynamic_cast<B*>(a);  //Would not throw std::bad_cast.
}

In the first case, an exception of std::bad_cast is generated, and in the second case no exception is generated - instead, the b pointer just is assigned the value NULL.

Can someone explain to me why only the former throws an exception when both are bad_cast examples? I figure there's a good motive behind the decision, and that I'm misusing something as I don't understand that motivation.

Can someone explain to me why only the former throws an exception?

That is how dynamic_cast is specified to behave: a bad dynamic_cast involving pointers yields a null pointer, but there are no null references, so a bad dynamic_cast involving references throws a bad_cast .

The fact that a failed dynamic_cast involving pointers yields a null pointer is useful because it allows for cleaner, simpler type checking and allows for the following idiom:

if (B* b = dynamic_cast<B*>(a))
{
    // The dynamic_cast succeeded and 'b' is non-null.
}

With this idiom, b is in scope and usable if and only if it is non-null.

References must be bound to an object that contains a valid memory address ... they cannot be "uninitialized", nor do they have a default non-bound initialization values. Note that section 8.5/8 in the C++11 standard states,

A program that calls for default-initialization or value-initialization of an entity of reference type is ill-formed.

Pointer variables on the other-hand are just memory addresses that contain values that point to other memory addresses and therefore can have a NULL value.

So if by the standard the dynamic_cast<T&> operation must return a valid memory address to bind to the reference variable, then if the dynamic cast fails, it can't return a "non-value" ... the only option is to throw an exception.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM