6
votes

With classes B and derived class D:

class B {
    int b;
};


class D : public B {
    int d;
};


D* d = new D();
B* b = dynamic_cast<B*>(d);

the above will work fine—it's a simple upcasting. We're sure that whatever b is pointing at has the B class (sub-)object in it.

However,

B* b = new D();
D* d = dynamic_cast<D*>(b);

won't compile even though b points to a valid D instance—because the base class is not polymorphic. So adding just one, empty virtual method would solve the problem.

The important question is why C++ requires the source type to be polymorphic? The only explanation I've found is this, but it merely states 'because that's how it's implemented internally' - at least in my eyes). People who designed dynamic_cast probably had some other reasons in mind - what were those?

2
I don't see anything dynamically polymorphic. You've been missing at least a virtual destructor in the base class.πάντα ῥεῖ
Please use a compiler, before posting code full of errors.user2249683
@DieterLücking True enough, but the exact code is not the essential part here. It was enough for demonstrating the intent, I would say.Angew is no longer proud of SO

2 Answers

4
votes

Because there is no way to implement dynamic_cast without some type information stored in the object for run-time use. And there are only two features of the language which need a run-time information on the object's type: virtual functions, and dynamic_cast.

If it was possible to use dynamic_cast to downcast non-polymorphic types, compliers would have to store run-time type information in every class type. This would go directly against the "only pay for what you use" philosophy of C++, and it would utterly break its compatibility with C and many external interfaces, hardware etc. There would be no standard-layout class types, basically. Or, alternatively, no class types where you could have full control of their layout.

3
votes

The premise of dynamic_cast is that it uses RTTI (presumably every implementation uses the same underlying data structure to support dynamic_cast and RTTI - the type info has to live somewhere and different representations for the two use cases makes no sense) to make sure that the cast you're attempting is to the correct type at runtime. If the from-class is non-polymorphic, the type information wouldn't be available to the compiler to do the type checking (to decided to return 0 or the converted pointer).