Showing posts with label dynamic_cast. Show all posts
Showing posts with label dynamic_cast. Show all posts

Wednesday, 9 January 2008

dynamic_casting with pointers and references

First of all a very warm happy new year to all the readers. Its been a while since the last post.

Today I intend to write about dynamic_cast again. There's already an article about dynamic_cast. The reason why I'm writing about this is to show with some samples how we can use dynamic cast with pointers and also with references.

Yes, RTTI can be implemented both with pointers and references.

Below sample shows how to use dynamic_cast with pointers. I have considered the same example classes which were there in the dynamic_cast article .

void ProcessButtonEvent(CControlIface *pControl)
{
    // Here we need make sure safe down-cast happens
    CButtonControl *pButton = dynamic_cast <CButtonControl *> (pControl);

    // casting works fine here since we had passed pControl1

    if(pButton != NULL)
    {
        pButton->OnClick();
        // We can now safely call OnClick() of CButtonControl
    }
    else
    {
        cout << "dynamic_cast failed. pControl is not pointing to instance of CButtonControl"<<endl;
    }
}

We need to note here that whenever dynamic cast fails with pointers it returns NULL. This is the reason why we are checking for

pButton!=NULL


Lets try dynamic casting with references,

void ProcessButtonEvent(CControlIface &Control)
{
    // Here we need make sure safe down-cast happens
    try{
    CButtonControl &Button = dynamic_cast <CButtonControl &> (Control);
    Button.OnClick();
    }
    catch(bad_cast)
    {
        cout << "Caught: bad_cast exception. This control is not a button"<<endl;
        return;
    }
}

In case of references if dynamic_cast fails, it throws bad_cast exception. This is the reason why we are catching the exception in the above code sample.

Please note that some old compilers may not support dynamic_cast. In that case its high time for you to upgrade your C++ compiler!

Sunday, 24 June 2007

dynamic_cast

Lets talk about Dynamic Casting today!

dynamic_cast is one of the four C++ casting operators (static_cast, dynamic_cast, reinterpret_cast and const_cast), extensively used in case of polymorphic types.

Unlike C type casting which does a static type check, this will do a type check at run time. If the casting is invalid, it either throws bad_cast exception or returns a NULL pointer.

This has to be used for safe run-time down casting.

What is Down casting?

Casting a superclass pointer (or reference) into a pointer (or reference) to a subclass in a class hierarchy is said to be down casting.

Typical example looks like this,


CDerived *pD = dynamic_cast<CDerived *>pB;


When to use?

Consider the scenario below,



Where the CControlIface is an abstract base class with a pure virtual function Draw(). There are two concrete classes implementing the CControlIface interface, CButtonControl and CTextControl which overrides the Draw()'s implementation. Also, they have their own methods


CButtonControl::OnClick()
CTextControl::OnKeyTyped()


The problem is how will we identify the type of object pointed at run-time, if we just have the base class pointer or reference?

The solution is dynamic_casting

Let's look into some code.


CControlIface *pControl1 = new CButtonControl();
CControlIface *pControl2 = new CTextControl();

...
...

ProcessButtonEvent(pControl1);
// No idea what pControl1 points to, at compile time

...
...

void ProcessButtonEvent(CControlIface *pControl)
{
    // Here we need make sure safe down-cast happens
    CButtonControl *pButton = dynamic_cast <CButtonControl *> pControl;

    // casting works fine here since we had passed pControl1

    ...

    if(pButton != NULL)
    {
        pButton->OnClick();
        // We can now safely call OnClick() of CButtonControl
    }
}


What would have happened if we had passed pControl2 while calling ProcessButtonEvent()?

dynamic_cast would have failed since pControl2 is not pointing to CButtonControl's instance. This check is performed by dynamic_cast operator at run-time using RTTI (Run-time Type Information).

Dynamic casting allows us to perform safe type conversions and lets our programs take appropriate actions when such casts fail.

Cheers!