C++ OStream 继承和操纵器
我有一个继承自 ostream
的类,但操纵器无法编译。例如:
QLogger &logger = QLogger::getInstance();
logger << hex << 10 << endl;
抱怨 logger <<十六进制。如果我将记录器转换为
ostream
,它会起作用,但这是相当笨拙的。
如何扩展我的类,使其表现得像带有操纵器的 ostream
?
谢谢,
肯尼
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 development 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;
};
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 development 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;
};
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果实现成员函数,则在重载决策中不会考虑该函数的继承重载。如果您将自定义
operator<<
重载更改为友元全局函数而不是成员,那么这应该可以正常工作。强制转换强制编译器从ostream
中定义的运算符中选择operator<<()
。不需要函数指针的特殊重载。
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 chooseoperator<<()
from those defined inostream
.The special overload for the function pointer isn't needed.