How C++ implements late binding
How can late
binding happen? All the work goes on behind the scenes
by the compiler, which installs the necessary late-binding mechanism when you
ask it to (you ask by creating virtual functions). Because programmers often
benefit from understanding the mechanism of virtual functions in C++, this
section will elaborate on the way the compiler implements this
mechanism.
The keyword
virtual tells the
compiler it should not perform early binding. Instead, it should automatically
install all the mechanisms necessary to perform late binding. This means that if
you call play( ) for a Brass object through an address for
the base-class Instrument, you’ll get the proper
function.
To accomplish this, the typical
compiler[54]
creates a single table (called the VTABLE) for each
class that contains virtual functions. The compiler places the addresses
of the virtual functions for that particular class in the VTABLE. In each class
with virtual functions, it secretly places a pointer, called the vpointer
(abbreviated as VPTR), which
points to the VTABLE for that object. When you make a virtual function call
through a base-class pointer (that is, when you make a polymorphic
call), the compiler quietly
inserts code to fetch the VPTR and look up the function address in the VTABLE,
thus calling the correct function and causing late binding to take
place.
All of this – setting up the VTABLE
for each class, initializing the VPTR, inserting the code for the virtual
function call – happens automatically, so you don’t have to worry
about it. With virtual functions, the proper function gets called for an object,
even if the compiler cannot know the specific type of the
object.
The following sections go into this
process in more
detail.