I have a class that inherits from ostream
but the manipulators fail to compile. For instance:
QLogger &logger = QLogger::getInstance();
logger << hex << 10 << endl;
Complains about logger << hex
. If I cast logger to an ostream
it will work but that is pretty ham-handed.
How can I extend my class so that it behaves as an ostream
with manipulators?
Thanks,
Kenny
class LIBEXPORT QLogger: public std::ostream
{
friend class boost::thread_specific_ptr< QLogger >;
friend class QLoggerFunnel;
public:
// Priority for message filtering.
//
// DEBUG Detailed information that may be useful during deve开发者_运维百科lopment or troubleshooting.
// NORMAL Message will be useful during normal operation.
// WARNING Message indicates an unhealthy condition but the system should continue to operate.
// FAULT Message indicates a critical error. The system may not operate normally.
enum Priority
{
DEBUG, NORMAL, WARNING, FAULT
};
// DEPRECATED: Defined for backward compatibility.
static const Priority LOW = NORMAL;
static const Priority HIGH = WARNING;
static const Priority URGENT = FAULT;
// Returns a reference to the global instance.
static QLogger& getInstance();
// DEPRECATED: Use instead: QLogger::instance() << "Example message." << std::endl
static AWI_DEPRECATED QLogger& stream( QLogger::Priority priority = NORMAL );
QLogger &operator<<( Priority p );
// Messages with a priority below the threshold are discarded.
void setThreshold( Priority priority );
Priority getThreshold( void ) const;
// Set the priority of messages.
void setPriority( Priority priority );
Priority getPriority( void ) const;
protected:
static void handleThreadExit( QLogger *logger );
QLogger();
QLogger( const QLogger& );
virtual ~QLogger();
QLogger& operator=( const QLogger& );
void write( std::ostream &destination );
void synchronize( void );
// Prepends information to each line of its associated output stream.
class StampBuffer: public std::stringbuf
{
public:
StampBuffer();
virtual ~StampBuffer();
// String to be displayed before each line.
void setPreamble( const char *p );
virtual int sync();
void write( std::ostream &destination );
protected:
boost::mutex _mutex;
std::stringstream _stream1;
std::stringstream _stream2;
// Active stream being written to.
std::stringstream *_write;
std::stringstream *_read;
const char *_preamble;
};
class NullBuffer: public std::stringbuf
{
public:
NullBuffer();
virtual ~NullBuffer();
virtual int overflow( int c )
{
return (c);
}
};
StampBuffer _buffer;
NullBuffer _null_buffer;
Priority _threshold;
Priority _priority;
};
If you implement a member function, then inherited overloads of that same function aren't considered in overload resolution. If you change your custom operator<<
overloads to be friend global functions rather than members, this should work fine. The cast forces the compile to choose operator<<()
from those defined in ostream
.
The special overload for the function pointer isn't needed.
精彩评论