Calls to Virtual Functions May Be Resolved at Run Time

When a virtual function is called through a reference or pointer, the compiler generates code to decide at run time which function to call. The function that is called is the one that corresponds to the dynamic type of the object bound to that pointer or reference.

As an example, consider our print_total function from §15.1 (p. 593). That function calls net_price on its parameter named item, which has type Quote&. Because item is a reference, and because net_price is virtual, the version of net_price that is called depends at run time on the actual (dynamic) type of the argument bound to item:

Quote base("0-201-82470-1", 50);
print_total(cout, base, 10);    // calls Quote::net_price
Bulk_quote derived("0-201-82470-1", 50, 5, .19);
print_total(cout, derived, 10); // calls Bulk_quote::net_price

In the first call, item is bound to an object of type Quote. As a result, when print_total calls net_price, the version defined by Quote is run. In the second call, item is bound to a Bulk_quote object. In this call, print_total calls the Bulk_quote version of net_price.

It is crucial to understand that dynamic binding happens only when a virtual function is called through a pointer or a reference.

base = derived;         // copies the Quote part of derived into base
base.net_price(20);     // calls Quote::net_price

When we call a virtual function on an expression that has a plain—nonreference and nonpointer—type, that call is bound at compile time. For example, when we call net_price on base, there is no question as to which version of net_price to run. We can change the value (i.e., the contents) of the object that base represents, but there is no way to change the type of that object. Hence, this call is resolved, at compile time, to the Quote version of net_price.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset