Showing posts with label RTTI. Show all posts
Showing posts with label RTTI. 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!

Saturday, 28 July 2007

RTTI

Run Time Type Information (RTTI) is the concept which facilitates us to identify type of a polymorphic object at run time (typeid operator) and to perform type-safe down casting. There is an article already in this blog about type-safe down-casting  - dynamic_cast.

typeid is an operator which can be used to find out the dynamic type of a polymorphic object. It can be used to identify the type of the object referenced by or pointed at run time.

When do we need to use it?

Ideally never. If we design the system properly we shouldn't be using this operator. But in certain cases where we cannot avoid, we may have to use typeid operator.

Let's look at an example.

class CShape
{
    ...
};

class CCircle : public CShape
{
    ...
};

class CRectangle : public CShape
{
    ...
};

void Draw(CShape *pShape)
{
    if(typeid(*pShape) == typeid(CCircle))
    {
        cout<<"Circle"<<endl;
    }
    else if(typeid(*pShape) == typeid(CSquare))
    {
        cout<<"Circle"<<endl;
    }
}

int main()
{
    CCircle *circle = new CCircle();
    CSquare *square = new CSquare();

    Draw(circle);
    Draw(square);
}

This prints "Circle" and "Rectangle".

In function Draw(), typeid is returning the polymorphic type of the object pointed by pShape which is unknown at compilation type.

typeid uses RTTI to find out the class type at run time.