In your program, B is derived from A, which means that all Bs are As, but not all As are Bs (All teacher are people, but not all people are teachers.) When B derives from A, the class B has everything contained in A as well as specialization information. In this case, the specialization information is an override of the f() function.
Since a B object is also an A object, you can point to it with an A* thus:
A* a = new B(1)
is legitimate.
Anywhere you need to pass an A object, you can use a B object instead. What happens is that the base class bits of the B object are used, and the specialization information is ignored.
This leads us to the
print ( *a );
line. What happens is that a object of class A is to be passed into the function. Because an object of type B is used, a temporary A object is created by copy constructor (from the sliced B object) and placed on the stack. This is an actual A object, not a B object as its originator, so the temporary object has A's version of the virtual f() function.
The
print ( a );
statement passes a pointer to the B object to its function. The object does not have to change. The original object, constructed as a B, has B's version of the virtual f() function.
A tutorial page from this web site which might help you better understand:
http://cplusplus.com/doc/tutorial/polymorphism/
I hope this helps.
p.s. Code tags, as SamuelAdams pointed to, would help in the future.