Virtual functions

In a real graphics program we create shapes at run time. Presumably we keep these shapes in some sort of list. What we would like is to keep all of our shapes in the same list so that we can just perform a loop through the list to draw each shape without caring about the actual shape class (circle, square...) e.g.
   for (int i=0;i<maxShapes;i++) shapeList[i]->draw();

shapeList is declared as an array of pointers to objects of the base class, shape. However, the pointers can actually point to any object derived from shape.
The compiler selects the virtual draw() function at run time based on the type of the pointed-to object not the declared type of the pointer.
In contrast, non-virtual functions are selected at compile time by using the declared class of the object on which the function operates.