The << and >> operators are still used for shift left and right as in C, but they are overloaded for C++
I/O. The compiler looks at the types of their operands to decide whether to generate code for a shift, or
for I/O. If the leftmost operand is a stream, I/O was intended. Using operators, not functions, has four
big advantages:
- The operators can be defined for every type. Thus, we do not need an individual function or
(equivalently) a string format specifier like "%d" for each different type. - There is some notational convenience in using an operator rather than a function when you
wish to output multiple messages. Just as you can write an expression i+j+k+l, the left-
associativity of the operator ensures that you can sensibly chain multiple I/O operands
together:
•
cout << "the value is " << i << endl;
- It provides an additional layer that simplifies format control and the use of functions like
scanf(). Let's face it, the scanf() family could certainly use a bit of simplifying (despite
the fact that the manual for it is quite short). - It is possible, and desirable, to overload the extract and insert operators (as these double
chevrons are called) for reading and writing an entire object as a single operation. This is just
an application of overloading as shown in the previous section.
You can make do with C's stdio.h functions in C++, but it's worthwhile to switch to the C++
features at an early point.
Polymorphism—Runtime Binding
Everyone has played nethack, so everyone knows that polymorphism is Greek for "many shapes." In
C++ it means supporting different methods for related objects, and allowing runtime binding to the
appropriate one. The mechanism by which this is supported in C++ is overloading—all the
polymorphic methods are given the same name, and the runtime system figures out which one is the
appropriate one. This is needed when you inherit: sometimes it's not possible to tell at compile time
whether you have an object of the base class or the inheriting class. The process of figuring this out
and calling the right method is called "late binding," and you tell the compiler you want it by applying
the virtual keyword to a method.
With ordinary compile-time overloading the signature of the functions must differ enough so that the
compiler can tell by looking at the argument types which function is intended. With virtual functions
the signatures must be identical and the polymorphism is resolved at run time. Polymorphism is the
last highlight of C++ that we will cover, and it is easier to explain with a code example than with text.
Software Dogma