Re: Having trouble with streams....
On Aug 12, 6:20 pm, SpreadTooThin <bjobrie...@gmail.com> wrote:
How does dgbEnter() get the name of the function?
These are some of the macros I've defined for the dbgFile class...
Probably really bad way to do it...
#define dbgEnter() (dbg.enter(typeid(*this).name(), __FUNCTION__))
That's fine. And what is __FUNCTION__? You're using a compiler
extension here, which isn't supported by most compilers.
#define dbgLeave() return(dbg.leave())
What does dgb.leave() return?
I've generally seen this handled by a macro along the lines of:
#define LOG_RETURN( value ) return dbg.logReturnValue( value ) ;
, where dgb.leave would be a function template along the lines
of:
template< typename T >
T const&
Debug::logReturnValue( T const& value )
{
if ( myIsActive ) {
myStream << value ; // plus all the usual stuff...
}
return value ;
}
This is only used when returning a value.
The logging of the actual returning takes place in the
destructor of the object which was created by the LOG_FUNCTION
macro.
#define dbgVLeave() (dbg.leave())
#define dbgReturn(x) return(dbg << "returning " << x << "\n", dbg.leave
(), (x))
#define dbgThrow(x) throw(dbg << "throwing " << x, dbg.leave(), x)
I got dbgBuf class working
1) class dbgBuf : public std::streambuf
2) class dbgFile : public std::ostream
dbgBuff ob;
std::ostream out(&ob)
Now that I've tested my streambuf sub class, I want to subclass
std::ostream.
There are some simple examples and a detailed explination of how
to do this at my site, but since my provider has decided to make
it inaccessable... (What he's actually done is disactivate the
old path, providing me with a new path. What he didn't do when
doing this was activate the new path, nor copy the pages over
from the old path. I've activated the new path, and I've found
a copy of the contents on one of my machines, but it probably
won't be before this week-end that I'm able to get it
reinstalled; since I have to reinstall everything anyway, I'll
do so with a newer version of my library---given that I don't
have an old version available---, which means modifying some of
the existing descriptive pages, *and* regenerating all of the
docs.)
However it would appear that I need a constructor in my new
derived class that knows what to do with a dbgBuf.
If you're passing it a dbgBuf directly, there's really no need
to derive. The usual reason for deriving from ostream is to
offer the client a single class which derives from istream, but
takes care of providing the new type of streambuf, and possibly
offers some additional functions only relevant to that type of
streambuf. Typically, the derived class will somehow contain an
instance of the derived streambuf (traditionally as a base class
to ensure that it is initialized before its address is passed to
ostream, but this is not necessary if your ostream is really
standard conforming), and about the only functions it will
provide are the constructors, a destructor and the const version
of rdbuf.
You might want to take a look at the implementation of ofstream
on your system, if you can access the sources.
What should dbgFile::dbgFile(dbgBuf &ob) do?
dbgFile::dbgFile(
dbgBuf& ob )
: std::ostream( ob )
{
}
But as I said, if that's all you're doing, don't bother---just
use std::ostream. (When I write a custom streambuf which is
only used in such an encapsulated use as here, I'll generally
just use istream or ostream directly, and not derived from them.
When I design a custom streambuf for more general use, on the
other hand, I'll always provide a convenience istream or
ostream:
template< typename Inserter >
class FilteringOStream
: private virtual Gabi::Util::DelegateWrapper<
FilteringOutputStreambuf< Inserter > >
, public std::ostream
{
public:
FilteringOStream(
std::ostream& dest,
Inserter i ) ;
explicit FilteringOStream( std::ostream& dest ) ;
FilteringOStream(
std::streambuf* dest,
Inserter i,
bool deleteWhenFinished
= false ) ;
FilteringOStream(
std::streambuf* dest,
bool deleteWhenFinished
= false ) ;
virtual ~FilteringOStream() ;
FilteringOutputStreambuf< Inserter >*
rdbuf() ;
} ;
(Don't worry about the delegate wrapper; just make the derived
streambuf a member. My code here dates from before the
standard, when I didn't have a guarantee that the ostream
constructor didn't actually use the streambuf whose pointer was
passed to it, so I had to ensure that the streambuf was fully
constructed before calling the ostream constructor.)
--
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