Lines 26 and 27 of Listing 22.4 show both functions qualified with the keyword virtual. This is important when functions are to be overridden, because it is the only way to make sure that class polymorphism works properly.
When a function outside an object calls a function in the object, the compiler generates code to perform the function call. If a function does not have the virtual keyword, the compiler assumes that the caller will want to call the function as implemented in the class the caller has at hand. Unfortunately, if the caller has a reference to a superclass of the class actually used to instantiate the object, and the derived class has overridden the function being called, the caller will not use the derived class's improved version of the function.
The keyword virtual tells the compiler that a function will be overridden in derived classes. The compiler prepares for this by performing any calls to that function through a function pointer. It maintains that function pointer to always point to the implementation of the function in the deepest derived class that overrode it.
This is especially powerful because it even works for calls from functions in the superclass to other member functions in the superclass. That is, a function in the superclass will end up calling the implementation of the function from the derived class if that function has the virtual keyword and if the instantiated object is actually of the derived class. That is exactly what the implementation of aPersistentTapeExternalInterface depends on.
Listing 22.5 shows one relevant section of the implementation of the superclass (anExternalInterface).
Lines 1–6 are the superclass implementation of GetOperatorChar(). Line 10 calls GetOperatorChar(). But in Listing 22.6 from aPersistentTapeExternalInterface, GetOperatorChar() is overridden to first read from the tape file. |
When, in the new implementation of main.cpp, main() gives Calculator aPersistentTapeExternalInterface, and Calculator calls myExternalInterface.NextRequest(), NextRequest() calls anExternalInterface::GetOperator() which, as a result of virtual, calls aPersistentTapeExternalInterface:: GetOperatorChar() rather than anExternalInterface:: GetOperatorChar(). This allows you to write only a very small amount of very specific code in aPersistentTapeExternalInterface and reuse most of the code in anExternalInterface. In fact, on lines 16 and 30 of Listing 22.6, aPersistentTapeExternalInterface even delegates any need for input from the console to the superclass function implementation. |
3.145.115.71