What is down-casting and how to make it safe?

Discussion in 'C' started by d_arin100, Oct 1, 2009.

1. d_arin100New Member

Joined:
Sep 25, 2009
Messages:
10
3
Trophy Points:
0
Location:
Bangalore

Introduction

This article explains what downcast are, how to make it safe, and so forth. However, before learning what downcast are, you must be familiar with polymorphism.

Background

Can you guess what is down-casting…yes it’s an opposite mechanism of up-casting. In upcast the inheritance hierarchy moving upwards. On the contrary of upcast in downcast mechanism the hierarchy moves downward. Upcasting is safe as its move up an inheritance hierarchy the classes always converge to more generic classes. Down-casting is potentially unsafe and a dilemma comes after making this. Let we have declared three classes “Circle”, “Square” & “Triangle” and all are derived from the base class “Shape”. Now “Circle” is a type of “Shape” (Which is upcast and safe) but if we downcast a “Shape”, it could be a “Circle” or “Square” or “Triangle”.

The code

Code:
#include <iostream>
using namespace std;

class Shape
{
};

class Circle : public Shape
{
};

class Square : public Shape
{
};

class Triangle : public Shape
{
};

int main()
{
Shape* pShape = new Circle; /// Upcast
/// This is unsafe since pShape holds a Circle pointer
/// and we are trying to cast it Square pointer
Square* pSquare = (Square*)(pShape); /// Downcast
/// Tring to cast it Circle* its ok since pShape holds a Circle pointer:
Circle* pCircle = (Circle*)(pShape); /// Downcast
}

Now C++ provides a type safe downcastoperation which is dynamic_cast. While we are using dynamic_castto a particular type, the return value indicates whether the cast is proper or not. If the return is non-zero then the cast is proper and successful otherwise it will return zero to indicate that this was not the correct type.
Code:
#include <iostream>
using namespace std;

class Shape
{
public:
virtual void f()
{
}
};

class Circle : public Shape
{
};

class Square : public Shape
{
};

class Triangle : public Shape
{
};

int main()
{
Shape* pShape = new Circle; /// Upcast

Square* pSquare = dynamic_cast<Square*>(pShape); /// Downcast

Circle* pCircle = dynamic_cast<Circle*>(pShape); /// Downcast

cout << "Square address = " << (long)pSquare << endl;
cout << "Circle address = " << (long)pCircle << endl;
}
Output:

The dynamic_cast use the information stored in the VTABLE to determine
the actual type, so while we are using a dynamic_cast there must be a virtual function. Here the “Shape” class contains a virtual function ("virtual void f()") and which is sufficient for creating the VTABLE.

Joined:
Jul 12, 2004
Messages:
15,358
383
Trophy Points:
83

Joined:
Nov 4, 2009
Messages:
40