C ++ - использование ostream в моем собственном классе - PullRequest
0 голосов
/ 23 февраля 2012

У меня проблемы с использованием ostream в моем классе логгера. По какой-то причине std :: endl никогда не распечатывается, поэтому новая строка не добавляется. Я уверен, что что-то не так, у меня проблемы с попыткой понять, как использовать мой ostream в моих собственных классах, поэтому я, вероятно, сделал что-то в корне неправильно.

class MyStreamBuf : public std::streambuf
{
    public:
    MyStreamBuf() : std::streambuf() 
    {

    }
};

class MyLogger : public std::ostream
{
public:
    MyLogger(MyStreamBuf* buf) : std::ostream(buf) { mBuf = buf; }
    ~MyLogger() { delete mBuf; }

    template <typename T>
    inline MyLogger& operator << (T const& value)
    {
#ifdef _WIN32 || _WIN64
        std::cout << value;
#endif

        return *this;
    }

    inline std::ostream& operator << (std::ostream& (*f)(std::ostream&))
    {

        return f(*this);
    }

    MyStreamBuf* mBuf;
};



int _tmain(int argc, _TCHAR* argv[])
{
    MyStreamBuf* buf = new MyStreamBuf();
    MyLogger logger(buf);
    logger << "kekekek" << "asdf: " << 23 << std::endl;
    logger << "kekekek" << "asdf: " << 23 << std::endl;;

    getchar();
    return 0;
}

Выход:

kekekekasdf: 23kekekekasdf: 23

Ответы [ 3 ]

3 голосов
/ 23 февраля 2012

Вы получили правильный подход при использовании пользовательского класса буфера потока. Однако именно здесь вы хотите реализовать конкретную логику, а не в классе, производном от std::ostream!

Просто чтобы объяснить, что происходит в данный момент: когда вы вызываете f(*this), функция f() вызывается с базой std::ostream, которая получает вывод и получает flush(). Твой класс полностью за кадром.

Вот что вы должны сделать: * удалите операторы вывода из вашего MyLogger класса * внедрите overflow() в ваш потоковый буфер, чтобы справиться с переполнением его буфера (например, отправить символы куда-либо или увеличить буфер) * реализовать sync() для отправки любых буферизованных символов и делать все остальное, что вам нужно сделать, когда поток очищается * вероятно MyLogger должен иметь буфер потока и правильно настроить его вазу; как правило, это все класс, производный от std::ostream делает

Было много примеров того, как это выглядит там. Ищите streambuf и Джеймса Канзе или меня, чтобы найти пару.

2 голосов
/ 23 февраля 2012

Попробуйте это:

inline std::ostream& operator << (std::ostream& (*f)(std::ostream&))
{
        std::cout << f;
        return *this;
}
1 голос
/ 23 февраля 2012

Вам нужно отправить endl куда-нибудь. Делая f(*this), вы пытаетесь отправить его себе, но у вашего объекта нет необходимых методов для этого. Если вы посмотрите на #include <ostream>, функция endl использует функцию put, чтобы поместить \n в поток, а затем сбросить его.

Вам нужно где-то написать конечную строку. Например, если вы пишете в cout, вы можете сделать

(*f)(std::cout);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...