Inheriting from fstream

T

Thomas Matthews

Hi,

My objective is to add enable & disable functionality to
the ofstream class. I want to have a log file where I
can disable and enable output to it. When my first
tests pass, I want to disable the annotations written
to the log file, but enable the text from the newer
test cases.

I've searched the C++ newsgroups and the FAQ-Lite
and didn't find anything relevant.

"The C++ Standard Library", by Josuttis, shows how
to modify an ostream class. I've successfully implemented
the enable/disable functions using a streambuf and
attached it to an ostream class.

I've also looked at Dietmar Kuhl's site and his
site explains how to modify an ostream but not an
ofstream.

However, I would like to add the functionality to
the file stream. The ofstream class does not provide
a constructor with a streambuf parameter (at least
Borland's compiler doesn't).

In summary, I would like to either subclass the
ofstream class or assign my streambuf to an
instance of the ofstream class. How do I go
about this?

#include <iostream>
#include <fstream>
#include <streambuf>
#include <cstdlib>
using namespace std;

class logfile
: public streambuf
{
public:
logfile()
: enabled(true)
{logstream.open("log.txt");}
bool enabled;
ofstream logstream;

protected:
virtual int_type overflow (int_type c)
{
if (enabled && (c != EOF))
{
logstream << c;
}
return c;
}
virtual streamsize xsputn(const char * s, streamsize num)
{
if (enabled)
{
logstream.write(s, num);
}
return num;
}
};


int main(void)
{
logfile lf;
ostream out(&lf);
out << "This should be printed.\n";
lf.enabled = false;
out << "This should not be printed.\n";
lf.enabled = true;
out << "After re-enabling.\n";

return EXIT_SUCCESS;
}

--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.raos.demon.uk/acllc-c++/faq.html
Other sites:
http://www.josuttis.com -- C++ STL Library book
 
J

John Harrison

Thomas Matthews said:
Hi,

My objective is to add enable & disable functionality to
the ofstream class. I want to have a log file where I
can disable and enable output to it. When my first
tests pass, I want to disable the annotations written
to the log file, but enable the text from the newer
test cases.

I've searched the C++ newsgroups and the FAQ-Lite
and didn't find anything relevant.

"The C++ Standard Library", by Josuttis, shows how
to modify an ostream class. I've successfully implemented
the enable/disable functions using a streambuf and
attached it to an ostream class.

I've also looked at Dietmar Kuhl's site and his
site explains how to modify an ostream but not an
ofstream.

However, I would like to add the functionality to
the file stream. The ofstream class does not provide
a constructor with a streambuf parameter (at least
Borland's compiler doesn't).

In summary, I would like to either subclass the
ofstream class or assign my streambuf to an
instance of the ofstream class. How do I go
about this?

Have you considered inheriting from filebuf (which is fstream's stream
buffer class) and then attaching your filebuf derived object to an ostream?

john
 
I

Ivan Vecerina

Thomas Matthews said:
My objective is to add enable & disable functionality to
the ofstream class. I want to have a log file where I
can disable and enable output to it. When my first
tests pass, I want to disable the annotations written
to the log file, but enable the text from the newer
test cases.

IIRC, disabling the output of a stream can be as simple
as setting an error flag ( using ios::clear() ) or
setting the stream buffer pointer it stores to NULL
( using rdbuf(NULL) ).

I do not remember the details of this, but it should
be simple enough and will not require any subclassing.


hth,
Ivan
 
T

Thomas Matthews

John said:
message news:[email protected]... [snip]
In summary, I would like to either subclass the
ofstream class or assign my streambuf to an
instance of the ofstream class. How do I go
about this?


Have you considered inheriting from filebuf (which is fstream's stream
buffer class) and then attaching your filebuf derived object to an ostream?

john

This works, but one has to use the "open" method of the
filebuf before writing begins; versus the constructor
of ofstream or fstream having the filename and mode
in the constructor.

Thanks for the suggestion.


--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.raos.demon.uk/acllc-c++/faq.html
Other sites:
http://www.josuttis.com -- C++ STL Library book
 
J

John Harrison

Thomas Matthews said:
John said:
message news:[email protected]... [snip]
In summary, I would like to either subclass the
ofstream class or assign my streambuf to an
instance of the ofstream class. How do I go
about this?


Have you considered inheriting from filebuf (which is fstream's stream
buffer class) and then attaching your filebuf derived object to an ostream?

john

This works, but one has to use the "open" method of the
filebuf before writing begins; versus the constructor
of ofstream or fstream having the filename and mode
in the constructor.

Thanks for the suggestion.

Yes, but you could wrap it all up in a class.

class LogBuffer : public filebuf
{
...
};

class LogStream : public ostream
{
public:
LogStream(const char*, int mode)
{
...
}
private:
LogBuffer buffer;
};

john
 

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,769
Messages
2,569,582
Members
45,062
Latest member
OrderKetozenseACV

Latest Threads

Top