как делают я пишу класс регистратора с интерфейсом стиля суда (регистратор <<“Ошибка”: <<val <<endl;)

Я хочу создать класс регистратора, таким образом что с функциональностью как это:

Logger log;
log << "Error: " << value << "seen" << endl;

Это должно распечатать меня пользовательское форматированное сообщение. Например, "09.12.2009 11:22:33 Ошибки 5 замеченных"

Мой простой класс в настоящее время похож на это:

class Logger {
    private:
        ostringstream oss;
    public:
        template <typename T>
        Logger& operator<<(T a);
}

template <typename T>
Logger& Logger::operator<<(T a) {
    oss << a;
    return *this;
}

void functionTest(void) {
    Logger log;
    log << "Error: " << 5 << " seen";
}

Это заставит oss правильно иметь буферную "Ошибку: 5 замеченных". Но я не знаю то, что другую функцию я должен писать/изменять так, чтобы что-то распечатало на экране. Кто-либо знает, как заставить это работать или является там другим способом разработать этот класс, чтобы иметь мою работу функциональности?

6
задан Jon Seigel 10 April 2010 в 18:36
поделиться

3 ответа

Насколько я понимаю, ваш регистратор ничем не отличается от ostringstream. Он просто берет то, что дано, и выводит это в поток строк. Если вы хотите использовать его таким образом, вы можете написать деструктор для Logger, который выводит строку в cout.

Logger::~Logger()
{
    std::cout<<getcurrentDateTimeAsString()<<" "<<oss.str()<<std::endl;
}

Но, конечно, это не имеет смысла, если Logger * создается и используется во всей программе.

1
ответ дан 17 December 2019 в 00:09
поделиться

За каждым std :: ostream стоит streambuf . Его можно получить и установить с помощью std :: stream :: rdbuf () . В частности, его можно обернуть - вы можете предоставить объект streambuf, который пост-обрабатывает передаваемый текст. ( постобработка означает, что вы не можете отличить std :: cout << 123; от std :: cout << "123"; )

В вашем конкретном случае постобработка довольно проста. В начале каждой строки вы хотите вставить несколько байтов. Это просто означает, что вы должны следить за тем, выводили ли вы уже префикс для текущей строки. Если нет, сделайте это и установите флаг. И всякий раз, когда вы видите новую строку, сбросьте ее. В вашей оболочке streambuf есть только одно состояние типа bool .

4
ответ дан 17 December 2019 в 00:09
поделиться

Это (из этого поста) делает то, что вы хотите, но это заставляет вас заканчивать каждую строку std::endl:

class Logger {
    private:
        ostringstream oss;
    public:
        template <typename T>
        Logger& operator<<(T a);

    Logger& operator<<( std::ostream&(*f)(std::ostream&) )
    {
        if( f == std::endl )
        {
            std::cout << "12-09-2009 11:22:33" << oss.str() << std::endl;   
            oss.str("");
        }
        return *this;
    }
};

template <typename T>
Logger& Logger::operator<<(T a) {
    oss << a;
    return *this;
}

void functionTest(void) {
    Logger log;
    log << "Error: " << 5 << " seen" << std::endl;
}

int main()
{
    functionTest();
}

EDIT: Ну, в соответствии с вашим комментарием, это не то, что вы хотите. Тогда я рекомендую вам делать то, что говорит MSalters.

0
ответ дан 17 December 2019 в 00:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: