Re: Deriving my own stream class
On Jun 17, 3:22 pm, Dan Smithers <dsmith...@talktalk.net> wrote:
kasthurirangan.bal...@gmail.com wrote:
[...]
Also, you may want to replace this
template <typename charT, typename Traits=std::char_traits<charT> >
with
template <typename charT, class Traits=std::char_traits<charT> >
I thought that class and typename were synonymous in this context.
They are. A lot of experts (but not all) prefer using typename
systematically in this case, to avoid confusion.
I didn't get why would want to write another stream for char
when its already available.
The reason why I'm doing this is that I have a log class that
opens a file and sends a string together with time information
to it.
That's easily done using a forwarding streambuf, see
http://kanze.james.neuf.fr/articles/fltrsbf1.html. More
generally, it is often desirable to make logging configurable,
etc., which often leads to a wrapper (not derivation) around
ostream; there's a generic implementation of this in the code at
my site (along with full implementations of output and input
filtering streambuf): go to the code section, then look up
OutputStreamWrapper in the IO subsection.
My initial implementation used a method log(const
string& msg) to do this, but that means that I have to
pre-format the string.
ostringstream oss;
oss << "log message" << log_val ...;
my_log(oss.str());
If I make my log class inherit from ostream then I can simply write
my_log << "log_message" << log_val ...;
You can do that with a wrapper as well. And if all you need is
the time stamp, a filtering streambuf means that you're using an
istream; you don't need to inherit (or if you do, it's only to
provide convenience constructors).
I thought that while I was doing this I would set up a
manipulator so that I can writethings like
my_log << setformat(Error) << "error message" << err_code;
my_log << setformat(Warning) << "warning message << warning_data;
This is most often handled by something like:
log( Log::error ) << "message" ... ;
log( Log::warning ) << "message" ... ;
The function "log" determines whether logging at this level is
active or not, and returns a corresponding OutputStreamWrapper.
Note that the destructor of the OutputStreamWrapper here can be
used to force a flush (and ensure that every log message ends
with a new line, if it collaborates with the filtering
streambuf), and the class itself can also grab a lock in its
constructor, and release it in the destructor, to ensure
synchronization in a multi-threaded environment.
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34