C++ Primer 4/e在Defining Base and Derived Classes这个地方有一个关键概念:‘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.’
中文版的这样写:‘References 和 pointers 的静态型别和动态型别可以不同,这个事实是C++多型的基石。
当我们透过一个base-class reference或pointer呼叫定义于base class内的函式时,我们并不知道该函式所处理的物件的精确型别,因为该物件可以是base type,也可以是derived type。
如果我们乎叫的是non-virtual函式,无论上述实际物件型别为何,被唤起的都是base定义的那个函式。但如果呼叫的是virtual函式,那么“唤起哪一个函式”的抉择会延至执行期。被执行起来的virtual函式版本是“reference 或 pointer所指物件的型别”所定义的那一个。
从程式编写的角度来看,我们不需要关心这些。只要classes正确设计并实作,这些函式就会做正确的事,不论实际物件是base type还是derived type。
另一方面,物件(而非references 或 pointers)不带多型性(不是polymorphic),因为其型别已知且不可能改变。物件的动态型别永远和其静态型别相同。经由物件而执行的函式,无论是virtual或non-virtual,唤起的都是该物件型别所定义的那一个。
注意:virtual函式只在“透过refenence或pointer被呼叫”时才于执行期决议。只有这样,才有可能“物件的动态型别于执行期才揭晓”。’
多型我必没有很懂,继续加油。