The ostream class provides the basic capability for sequential and random-access output. An ostream object has a streambuf-derived object attached, and the two classes work together; the ostream class does the formatting, and the streambuf class does the low-level buffered output.
You can use ostream objects for sequential disk output if you first construct an appropriate filebuf object. (The filebuf class is derived from streambuf.) More often, you will use the predefined stream objects cout, cerr, and clog (actually objects of class ostream_withassign), or you will use objects of classes ofstream (disk file streams) and ostrstream (string streams).
All of the ostream member functions write unformatted data; formatted output is handled by the insertion operators.
It is not always necessary to derive from ostream to add functionality to a stream; consider deriving from streambuf instead, as illustrated in Chapter 19 of the Class Libraries User's Guide. The ofstream and ostrstream classes are examples of ostream-derived classes that construct member objects of predetermined derived streambuf classes.
You can add manipulators without deriving a new class.
If you add new insertion operators for a derived ostream class, then the rules of C++ dictate that you must reimplement all the base class insertion operators. If, however, you reimplement the operators through inline equivalence, no extra code will be generated. For example,
class xstream : public ostream
{
public:
// Constructors, etc.
// ........
inline xstream& operator << ( char ch ) // insertion for char
{
return (xstream&)ostream::operator << ( ch );
}
// ........
// Insertions for other types
};
#include <iostream.h>
streambuf, ofstream, ostrstream, cout, cerr, clog