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!

1 comment:

KK said...

One thing I have always wondered about is: why use a base class pointer to point to a derived object? Is the primary purpose to try and save run-time memory or optimize for speed? (Derived class = bigger and slower)

One other use was, using non-friend functions directly.

In any case, I would benefit a lot if you enumerated some sample cases where its useful to have a base class object pointer point to a derived class object pointer.