I am writing a class that has various messages output. I want to make this class general and platform independent, so I am thinking of passing a basic_ostream reference to it and it can dump all the messages into the stream. By doing this, if the class is used in a console program, I can pass std::cout to it and display in console window.
Or I could pass a derived ostream to it and redirect the message to some UI components, e.g. ListBox? The only problem is the data inserter operator << is not a virtual function. If I pass the derived class reference to it, only the basic_ostream << operator will be called. 
Is there any workaround for this?
Nan Zhang's own answer, originally posted as part of the question:
Follow up: OK, here is the derived std::streambuf that implements required functionality:
class listboxstreambuf : public std::streambuf { 
public:
    explicit listboxstreambuf(CHScrollListBox &box, std::size_t buff_sz = 256) :
            Scrollbox_(box), buffer_(buff_sz+1) {
        char *base = &buffer_.front();
        //set putbase pointer and endput pointer
        setp(base, base + buff_sz); 
    }
protected:
    bool Output2ListBox() {
        std::ptrdiff_t n = pptr() - pbase();
        std::string temp;
        temp.assign(pbase(), n);
        pbump(-n);
        int i = Scrollbox_.AddString(temp.c_str());
        Scrollbox_.SetTopIndex(i);
        return true;
    }
private:
    int sync() {
        return Output2ListBox()? 0:-1;
    }
    //copying not allowed.
    listboxstreambuf(const listboxstreambuf &);
    listboxstreambuf &operator=(const listboxstreambuf &);
    CHScrollListBox &Scrollbox_;
    std::vector<char> buffer_;
};
To use this class just create a std::ostream and initialize with this buffer
std::ostream os(new listboxstreambuf(some_list_box_object));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With