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: Cpp
#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
}
Code: Cpp
#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:
Square address = 0
Circle address = 4726144 (This is address of the circle object)
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.

