It’s important to realize that
upcasting deals only with addresses. If the compiler has
an object, it knows the exact type and therefore (in C++) will not use late
binding for any function calls – or at least, the compiler doesn’t
need to use late binding. For efficiency’s sake, most compilers
will perform early binding when
they are making a call to a virtual function for an object because they know the
exact type. Here’s an example:
In p1–>speak( ) and
p2.speak( ), addresses are used, which means the information is
incomplete: p1 and p2 can represent the address of a Pet
or something derived from Pet, so the virtual mechanism must be
used. When calling p3.speak( ) there’s no ambiguity. The
compiler knows the exact type and that it’s an object, so it can’t
possibly be an object derived from Pet – it’s exactly
a Pet. Thus, early binding is probably used. However, if the compiler
doesn’t want to work so hard, it can still use late binding and the same
behavior will
occur.