<TABLE style="TABLE-LAYOUT: fixed">
The crucial point about references and pointers to base-class types is that the static typethe type of the reference or pointer, which is knowable at compile timeand the dynamic typethe type of the object to which the pointer or reference is bound, which is knowable only at run timemay differ.
The fact that the static and dynamic types of references and pointers can differ is the cornerstone of how C++ supports polymorphism.
When we call a function defined in the base class through a base-class reference or pointer, we do not know the precise type of the object on which the function is executed. The object on which the function executes might be of the base type or it might be an object of a derived type. If the function called is nonvirtual, then regardless of the actual object type, the function that is executed is the one defined by the base type. If the function is virtual, then the decision as to which function to run is delayed until run time. The version of the virtual function that is run is the one defined by the type of the object to which the reference is bound or to which the pointer points. From the perspective of the code that we write, we need not care. As long as the classes are designed and implemented correctly, the operations will do the right thing whether the actual object is of base or derived type.On the other hand, an object is not polymorphicits type is known and unchanging. The dynamic type of an object (as opposed to a reference or pointer) is always the same as the static type of the object. The function that is run, virtual or nonvirtual, is the one defined by the type of the object.
Virtuals are resolved at run time only if the call is made through a reference or pointer. Only in these cases is it possible for an object’s dynamic type to be unknown until run time.