Thursday, February 4, 2010

UpCasting and DownCasting in C++

Upcasting - UpCasting is defined as casting a pointer or reference of a derived class type to a type of a pointer or reference to a base class. In case of virtual function implementation we can cast a derived class pointer or reference to base class

Downcasting is defined as casting a pointer or reference of a base class type to a type of a pointer or reference to a derived class.
Mostly used to restore the object to its original type.


Downcasting can lead to trouble due to contravariance, e.g.:

struct Base {
int i_;
virtual int foo (void) { return i_; }
};
struct Derived : public Base {
int j_;
virtual int foo (void) { return j_; }
};
void foo (void) {
Base b;
Derived d;
Base *bp = &d; // "OK", a Derived is a Base
Derived *dp = &b;// Error, a Base is not necessarily a Derived
}

Problem: what happens if dp->j_ is referenced or set?

Since a Derived object always has a Base part certain operations
are ok:
bp = &d;
bp->i_ = 10;
bp->foo (); // calls Derived::foo ();
Since base objects don’t have subclass data some operations aren’t
ok
– e.g., accesses information beyond end of b:
dp = (Derived *) &b;
dp->j_ = 20; // big trouble!

C++ permits contravariance if the programmer explicitly casts, e.g.,
dp = (Derived *) &b; // unchecked cast

RTTI can be used to check the type of the object

if (Derived *dp = dynamic_cast(&b))
/* use dp */;
else
/* error! */
For a dynamic cast to succeed, the “actual type” of b would have to
either be a Derived object or some subclass of Derived

dynamic_cast throw bad_cast exception in case of failure
if the types do not match the operation fails at run-time

1 comment:

  1. I had a tough time to understand this feature.. Your post convinced me to the best.

    Thanks,

    ReplyDelete