Overload handling of std::endl?

后端 未结 7 1040
广开言路
广开言路 2020-11-27 04:40

I want to define a class MyStream so that:

MyStream myStream;
myStream << 1 << 2 << 3 << std::endl << 5 << 6         


        
7条回答
  •  伪装坚强ぢ
    2020-11-27 05:10

    What you need to do is write your own stream buffer: When the stream buffer is flushed you output you prefix characters and the content of the stream.

    The following works because std::endl causes the following.

    1. Add '\n' to the stream.

    2. Calls flush() on the stream

    3. This calls pubsync() on the stream buffer.

      1. This calls the virtual method sync()
      2. Override this virtual method to do the work you want.
    #include 
    #include 
    
    class MyStream: public std::ostream
    {
        // Write a stream buffer that prefixes each line with Plop
        class MyStreamBuf: public std::stringbuf
        {
            std::ostream&   output;
            public:
                MyStreamBuf(std::ostream& str)
                    :output(str)
                {}
                ~MyStreamBuf() {
                    if (pbase() != pptr()) {
                        putOutput();
                    }
                }
       
            // When we sync the stream with the output. 
            // 1) Output Plop then the buffer
            // 2) Reset the buffer
            // 3) flush the actual output stream we are using.
            virtual int sync() {
                putOutput();
                return 0;
            }
            void putOutput() {
                // Called by destructor.
                // destructor can not call virtual methods.
                output << "[blah]" << str();
                str("");
                output.flush();
            }
        };
    
        // My Stream just uses a version of my special buffer
        MyStreamBuf buffer;
        public:
            MyStream(std::ostream& str)
                :std::ostream(&buffer)
                ,buffer(str)
            {
            }
    };
    
    
    int main()
    {
        MyStream myStream(std::cout);
        myStream << 1 << 2 << 3 << std::endl << 5 << 6 << std::endl << 7 << 8 << std::endl;
    }
    
    > ./a.out
    [blah]123 
    [blah]56 
    [blah]78
    >
    

提交回复
热议问题