Reputation: 13417
I have the following code:
using namespace std;
class BaseOk
{
public:
virtual void ImplementMe()
{
};
};
class DerivedOk : public BaseOk
{
public:
void ImplementMe()
{
}
};
class CBase { };
class CDerived: public CBase { };
int main()
{
CBase b; CBase* pb;
CDerived d; CDerived* pd;
pb = dynamic_cast<CBase*>(&d); // ok: derived-to-base
pd = dynamic_cast<CDerived*>(&b); // wrong: base-to-derived -> this doesn't compile
// Polymorphic case
BaseOk b2; BaseOk* pb2;
DerivedOk d2; DerivedOk* pd2;
pb2 = dynamic_cast<BaseOk*>(&d2); // ok: derived-to-base
pd2 = dynamic_cast<DerivedOk*>(&b2); // wrong: base-to-derived -> this returns a NULL pointer
}
The line with the pointer "pd" performs a downcast and I agree that it should fail because the result is a totally different object. My question is: why doesn't the dynamic_cast in that line compile at all instead of just returning a NULL pointer?
I'm using MSVC2012 compiler
Upvotes: 2
Views: 432
Reputation: 254471
Using dynamic_cast
on a pointer to a non-polymorphic type is an error. That's a diagnosable rule, so you should get a compile-time error.
Using it on a pointer to a polymorphic type which is not convertible to the target type is not an error, and in any case is not generally detectable when compiling. It has well-defined behaviour, giving a null pointer.
Upvotes: 2
Reputation: 69988
Why doesn't the
dynamic_cast
in that line compile at all instead of just returning a NULL pointer?
Consider this as a feature/facility rather than a limitation.
dynamic_cast
is a mechanism where we would find the RTTI (run-time type information) of an object based on the pointer/reference.
Now suppose if a class is not at all polymorphic (i.e. doesn't contain any virtual
method), then definitely the dynamic_cast
will always fail.
Which means you don't have to use the dynamic_cast
where there is a 0 probability of passing. Why should you waste machine cycles on the thing which is known at compile time? That's why compiler provides you the facility straight away.
There is another hidden advantage of this. Suppose you are using dynamic_cast
with references, if it fails then an exception is thrown. Would anyone want to handle an exception for something which is already known at compile time!
Upvotes: 2