C++ ostream Output

ostream Output
The goal is to make a class outputtable to an ostream, like this: A a; cout << "The value of A is: " << a << endl;

Overloading operator <<
This can be achieved by overloading operator << to handle the A class. The operator will probably need access to private members of the class, so we declare it a friend of the class: class A { friend ostream & operator << (ostream & out, const A &); int value_; }; ostream & operator << (ostream & out, const A & a) { return out << a.value_; } The operator and friend must be declared for each class, which ends up being pretty error-prone.

operator << Explained
The operator can be used like this: out << a << " " << b; which is equivalent to: (((out << a) << " " ) << b); To clarify, we can replace operator<< with a print-method with the same type: ostream & print(ostream & out, const A & a); Which could be used like this: print( print( print(out, a), " "), b);

operator<< Is Not Polymorphic
Defining operator<< for each class has a problem:
 * operator<< is not a method.

Printing an instance of a class will always use the static type of the instance, not the dynamic type. Thus you cannot print objects polymorphically.

Take a look at the following example: class A { }; ostream & operator <<(ostream & out, const A & a) { out << "I am an A"; return out; } class B : public A { }; ostream & operator <<(ostream & out, const B & b) { out << "I am a B"; return out; }

B b; A & a = b; cout << a << endl; The result is: I am an A even though a is an instance of class B.

Printing Using a Method
To use polymorphism, we have to make operator<< a method instead. Here is a naive example: class A { public: virtual ostream & print( ostream & out ) const; }; A a, b; b.print( a.print( out )); Using this approach is unbearably ugly and doesn't work with built-in types.

Solution
The solution for this problem is a combination of a method and an operator<<. class A { public: virtual void print(ostream & out) const { out << "I am an A"; } }; inline ostream & operator << ( ostream & out, const A & a ) { a.print(out); return out; } All printable base classes should have an operator << that calls print on the second argument. Thus, we get the nice syntax, polymorphism, and as an added bonus, we can completely drop the friend declaration, because print is now a method.

Polymorphism works, as you can see from this example: class A { public: virtual void print(ostream & out) const { out << "I am an A"; } }; ostream & operator <<(ostream & out, const A & a) { a.print(out); return out; } class B : public A { public: virtual void print(ostream & out) const { out << "I am a B"; } };

B b; A & a = b; cout << a << endl; Which outputs: I am a B

Printable Interface
The ultimate solution reduces all the operator<< declarations to a single declaration. This is simply accomplished by declaring a Printable interface. To make a new class ostream outputtable, you only need to implement a print method. Here's the interface: namespace N { class Printable { // interface class public: virtual ~Printable {} virtual void print(ostream & out) const = 0; };   inline ostream & operator << ( ostream & out, const Printable & p ) { p.print(out); return out; } } Declaring operator<< inside a namespace is important if you use other namespaces. It allows us to easily access it inside another namespace by 'using namespace N'.

Here's an example implementation of the Printable interface: class A : Printable { public: virtual void print(ostream & out) const { out << "I am an A"; } }; And an example of outputting A inside another namespace: namespace M { using namespace N; // get the operator<< A a;   cout << a << endl; }