deriving from ostream - Logger

C

Christopher Pisz

I set out to make a custom logger. Examining some other code laying around,
I came across one that derived from ostream, and had a associated class
derived from streambuf. Is this practice a good idea? I was under the
impression that deriving from std classes that do not have virtual methods
was bad. Is ostream designed to be derived from?

If, so are there any resources on how to do this properly? ostream has alot
if internals that look pretty difficult to..for loss of words...understand
completely.

Thanks.
 
J

James Kanze

I set out to make a custom logger. Examining some other code
laying around, I came across one that derived from ostream,
and had a associated class derived from streambuf. Is this
practice a good idea?

It depends on how you implement the framework. In my case, the
"logger" is the return value of a function, which means that it
must support copy, and so deriving from ostream is out. Other
architectures are certainly possible, however, and if copy isn't
necessary, deriving from ostream is probably a good solution.
I was under the impression that deriving from std classes that
do not have virtual methods was bad.

So how does that affect ostream. Ostream has a virtual
destructor.
Is ostream designed to be derived from?

Definitly. What do you think ofstream and ostringstream do?
If, so are there any resources on how to do this properly?
ostream has alot if internals that look pretty difficult
to..for loss of words...understand completely.

For the most part, you derive from ostream for convenience: to
automatically create and destroy the desired type of streambuf.
It's also usual to provide rdbuf(), to return a pointer to the
derived type of streambuf.

In the case of a logger based on a temporary, it might make
sense to add some special "end of log record" handling in the
destructor. Plus some special function which returns a
non-const reference, to kick things off (and allow the use of
non-member << operators). Something like:

#define LOG( level ) \
ologstream( level ).start( __FILE__, __LINE__ )

for example: the constructor of ologstream connects to a
streambuf according to the level, the start function outputs the
filename and linenumber, and returns an ostream& so that all <<
operators can be used, and the destructor calls a special
function on the streambuf which flushes (but also ensures that
the output is correctly terminated with a '\n', etc.).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,074
Latest member
StanleyFra

Latest Threads

Top