Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

inheritance - How to inherit from std::ostream?

I've been googling around and I just can't find a simple answer to this. And it should be simple, as the STL generally is.

I want to define MyOStream which inherits publicly from std::ostream. Let's say I want to call foo() each time something is written into my stream.

class MyOStream : public ostream {
public:
  ...
private:
   void foo() { ... }
}

I understand that the public interface of ostream is non-virtual, so how can it be done? I want clients to be able to use both operator<< and write() and put() on MyOStream and have use the extended ability of my class.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I was spinning my head around how to do the same thing and i found out it's actually not that hard. Basically just subclass the ostream and the streambuf objects, and construct the ostream with itself as the buffer. the virtual overflow() from std::streambuf will be called for every character sent to the stream. To fit your example i just made a foo() function and called it.

#include <iostream>

struct Bar :  private std::streambuf , public std::ostream
{
    Bar() : std::ostream(this) {}

private:
    int overflow(int c) override
    {
        foo(c);
        return 0;
    }


    void foo(char c)
    {
        std::cout.put(c);

    }
};

int main()
{
    Bar b;
    b<<"Look a number: "<<std::hex<<29<<std::endl;

    return 0;
}

EDIT: The old code used the wrong initialization order. Although it had no visible side effects, the streambuf object should be initialized before passing it to the ostream object. Since C++ initializes parents left to right, I moved std::streambuf to the left to make the code correct.

EDIT: I changed the code to inherit std::streambuf privately to keep the interface cleaner and keep the class encapsulated.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...