C++ : Input/output via <iostream.h> and <stdio.h>


PART 7


Q29: How can I provide printing for a `class X'?
A: Provide a friend operator<<:
    class X {
      int i;    //just for illustration
    public:
      friend ostream& operator<<(ostream& o, const X& x) { return o << x.i; }
      //...
    };

We use a friend rather than a member since the `X' parameter is 2nd, not 1st.
Input is similar, but the signature is:
	istream& operator>> (istream& i, X& x);  //not `const X& x' !!



Q30: Why should I use <iostream.h> instead of the traditional ?
A: See next question.



Q31: Printf/scanf weren't broken; why `fix' them with ugly shift operators?
A: The overloaded shift operator syntax is strange at first sight, but it
quickly grows on you.  However syntax is just syntax; the real issues are
deeper.  Printf is arguably not broken, and scanf is perhaps livable despite
being error prone, however both are limited with respect to what C++ I/O can
do.  C++ I/O (left/right shift) is, relative to C (printf/scanf):
 * type safe -- type of object being I/O'd is known statically by the compiler
	rather than via dynamically tested '%' fields
 * less error prone -- redundant info has greater chance to get things wrong
	C++ I/O has no redundant '%' tokens to get right
 * faster -- printf is basically an `interpreter' of a tiny language whose
	constructs mainly include '%' fields.  the proper low-level routine is
	chosen at runtime based on these fields.  C++ I/O picks these routines
	statically based on actual types of the args
 * extensible -- perhaps most important of all, the C++ I/O mechanism is
	extensible to new user-defined data types (imagine the chaos if
	everyone was simultaneously adding new incompatible '%' fields to
	printf and scanf?!).  Remember: we want to make user-defined types
	(classes) look and act like `built-in' types.
 * subclassable -- ostream and istream (the C++ replacements for FILE*) are
	real classes, and hence subclassable.  This means you can have other
	user defined things that look and act like streams, yet that do
	whatever strange and wonderful things you want.  You automatically
	get to use the zillions of lines of I/O code written by users you
	don't even know, and they don't need to know about your `extended
	stream' class.  Ex: you can have a `stream' that writes to a memory
	area (incore formatting provided by the standard class `strstream'),
	or you could have it use the stdio buffers, or [you name it...].