As we’ve seen, in C++ dynamic binding happens when a virtual member function is called through a reference or a pointer to a base-class type (§15.1, p. 593). Because we don’t know which version of a function is called until run time, virtual functions must always be defined. Ordinarily, if we do not use a function, we don’t need to supply a definition for that function (§6.1.2, p. 206). However, we must define every virtual function, regardless of whether it is used, because the compiler has no way to determine whether a virtual function is used.
Exercise 15.8: Define static type and dynamic type.
Exercise 15.9: When is it possible for an expression’s static type to differ from its dynamic type? Give three examples in which the static and dynamic type differ.
Exercise 15.10: Recalling the discussion from §8.1 (p. 311), explain how the program on page 317 that passed an ifstream
to the Sales_data read
function works.
Key Concept: Conversions among Types Related by Inheritance
There are three things that are important to understand about conversions among classes related by inheritance:
• The conversion from derived to base applies only to pointer or reference types.
• There is no implicit conversion from the base-class type to the derived type.
• Like any member, the derived-to-base conversion may be inaccessible due to access controls. We’ll cover accessibility in §15.5 (p. 613).
Although the automatic conversion applies only to pointers and references, most classes in an inheritance hierarchy (implicitly or explicitly) define the copy-control members (Chapter 13). As a result, we can often copy, move, or assign an object of derived type to a base-type object. However, copying, moving, or assigning a derived-type object to a base-type object copies, moves, or assigns only the members in the base-class part of the object.