First lets define a few concepts: class hierarchy, upcast, downcast.
A class hierarchy in UML is often visualized as a class tree (sometimes graph) the way this picture illustrates:
http://www.ccs.neu.edu/research/demeter/personalities/luis/example/Image1.gif[
^]
As you see the root of the tree is the base class and it is at the top of the picture. If you have a pointer to a derived class instance and you cast the pointer into a pointer of one of its base classes then you are doing an "upcast" because you cast from one of the lower nodes of the hierarchy tree to another node that is higher in the tree. This type of cast is safe and straightforward so you don't even have to indicate this cast for the compiler, it will do the cast automatically:
class Base {};
class Derived : public Base {};
Derived* d = blahblah;
Base* b = d;
However when you cast from a base class to a derived class it is called a downcast that is considered unsafe. The compiler doesn't know whether a base class pointer of type "Animal" points to a Tiger instance or a Mouse instance... But if the base class has a vtable (because it has at least 1 virtual method) then you can use dynamic_cast to ask the compiler to generate some code that finds out whether your base class pointer points to a particular subclass instance or not:
class Base
{
virtual ~Base() {}
};
class Derived1 : public Base {};
class Derived2 : public Base {};
Base* b = new Derived1;
Derived1* d1 = dynamic_cast<derived1*>(b); Derived2* d2 = dynamic_cast<derived2*>(b);
dynamic_cast uses the typeinfo found in the vtable (usually at a negative offset below the method pointers) thats why your base class has to have at least one virtual function.
Final notes: using dynamic_cast (and downcast in general in programming in any object oriented language) defeats the purpose of polimorphism. Its like using if-then-else instead of true object oriented design. Using downcasts in an object oriented program (dynamic_cast in C++) is a strong indicator of bad code/OO design. Another drawback is that dynamic_cast can be relatively slow compared to other kind of safe casts.
If your code has dynamic_casts in it then your OO design sucks! I allow using dynamic_cast for myself at most once a year only in case of hotfixes when a little dirty hack is excepted instead of a redesign and the code is not performance critical.