Up-casting is built into C++ and is frequently used when dealing with virtual dispatching.
In other words, you have a reference to Base from which you can access the common interface of an entire hierarchy of classes, and you may pick them at runtime.
This implies that your interface functions have been designated as virtual.
Example:
Base* pBase;
cin >> x;
if(x == 0) // this is done at runtime, as we don't know x at compile time
pBase = new Derived1;
else
pBase = new Derived2;
pBase->draw(); // draw is a virtual member function
It is especially handy in instances when the dispatch is performed at runtime.
Simply enough, upcasting allows you to treat a derived class as if it were a base class (via its common interface).
Downcasting is less beneficial and, in my opinion, should be avoided wherever possible.
In general, this is a symptom of poor design because it is uncommon to need to transform a Base object to a derived one.
It is possible to do so (and have the outcome validated) using dynamic cast.
Base* pBase = new Derived; // OK, the dynamic type of pBase is Derived
Derived* pDerived = dynamic_cast<Derived*>(pBase);
if(pDerived) // always test
{
// success
}
else
{
// fail to down-cast
}