Pointer to base knows only about members of base. Derived type object has those members.
Pointer to derived expects that the pointed to object has all the members that derived has, but a base type object does not have members of the derived.
One can declare a function that takes a pointer to a base class, but when one calls the function, it is with a derived class pointer.
This works because the compiler stores a pointer to it's parent class for each derived class, So it can tell whether the pointer to derived class is a valid in relation to the base class, by "navigating" up the inheritance tree.
This is a very handy feature, as it saves having to write lots of functions for every derived class. Instead, the function (whether it be virtual, or pure virtual ) is inherited, then over-ridden to perform specialised behaviour as required.
An example is a simple Units conversion program, where the goal is to convert say any distance unit to any other distance unit, or convert Areas, Volumes, Temperature etc.
So, one could have a base class called Units, with derived classes called Distance, Area, Volume, Temperature etc. Then further derived classes for each Unit - Metres, Feet, Yards etc.
Now the Units class has 2 pure virtual functions called ToMetric and FromMetric which both take 2 (smart) pointers to the Units Class. Then each of the derived classes Metres, Feet, Yards etc redefines those 2 functions to do the appropriate calculation. The idea is to do the conversion in 2 stages (to metres say and from metres say), greatly reducing the of functions to be written - 2 per unit as opposed the numbers of units squared ( 2n vs n(n-1) )
When the functions are called, the arguments are pointers to variables of the type that one is converting from and to.
Hope this all makes sense, and helps out a bit.
Edit: As per usual, way too many distractions & slow typing ....