Domanda

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

È stato utile?

Soluzione

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!

Altri suggerimenti

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top