C++ OStream 继承和操纵器

发布于 2024-11-30 20:43:05 字数 3096 浏览 0 评论 0原文

我有一个继承自 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

愚人国度 2024-12-07 20:43:05

如果实现成员函数,则在重载决策中不会考虑该函数的继承重载。如果您将自定义 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 choose operator<<() from those defined in ostream.

The special overload for the function pointer isn't needed.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文