How can I provide printing for an entire hierarchy of classes?
Provide a friend operator<< that calls a protected virtual function: class Base { public: friend ostream& operator<< (ostream& o, const Base& b); // ... protected: virtual void print(ostream& o) const; }; inline ostream& operator<< (ostream& o, const Base& b) { b.print(o); return o; } class Derived : public Base { protected: virtual void print(ostream& o) const; }; The end result is that operator<< acts as if it was dynamically bound, even though it's a friend function. This is called the Virtual Friend Function Idiom. Note that derived classes override print(ostream&) const. In particular, they do not provide their own operator<<. Naturally if Base is an ABC, Base::print(ostream&) const can be declared pure virtual using the "= 0" syntax.