Завершено
2
06.12.2024, 09:45
17.12.2024, 04:32
Реализовать логгер.
Примерный интерфейс логгера.
class logstream {
    // реализация ...
public:
    static void set_log_file(const std::string & name);
    logstream(void);
    ~logstream(void);
    template < typename T >
    inline logstream & operator << (const T & rhs) {
        // ...
        return *this;
    }
    // ...
};
set_log_file – статический метод класса, позволяющий назначить файл журнала. Если в момент вызова журнал уже был открыт, то старый файл сохраняется и закрывается, отрывается новый файл, и в дальнейшем, журнал ведётся уже в него.
конструктор – конструируется "легковесный" объект, предоставляющий доступ к одному единственному файловому потоку, ведущему запись в журнал.
деструктор – "легковесный" объект уничтожается, при этом файловый поток, ведущий запись в журнал сбрасывает все буферизованные данные в файл, но сам файл не закрывает и продолжает вести запись.
operator << – перегруженный оператор вывода в поток. При передаче в поток манипулятора endl, происходит принудительный сброс буферизованных данных в файл журнала.
Допускается реализация, в которой файловый поток закрывается в моменты когда нет ни одного "легковесного" logstream. В этом случае, при создании хотя бы одного logstream, файловый поток открывается снова в режиме дозаписи файла.
Пример использования
int f(int a) {
    logstream log;
    log << "f(0x" << std::hex << a << ")" << std::endl;
    int r = a * a;
    log << "f() -- return " << r << std::endl;
    return r;
}
void main(void) {
    logstream::set_log_file("test.log");
    logstream log;
    log << "main()" << std::endl;
    f(15);
    log << "main() -- return" << std::endl;
}
Желающие дополнительно повысить оценку за задачу могут реализовать назначение префикса, который указывается при конструировании logstream и добавляется в поток в начале каждой строки.
В этом случае в интерфейсе logstream
logstream(const std::string & prefix = std::string());
Использование:
int f(int a) {
    logstream log("f()");
    log << " a = 0x" << std::hex << a << std::endl; // вывод "f() a = 0xf\n"
    int r = a * a;
    log << " return " << r << std::endl;            // вывод "f() return 225\n"
    return r;
}
void main(void) {
    logstream::set_log_file("test.log");
    logstream log("main()");
    f(15);
    log << " return" << std::endl;                 // вывод "main() return\n"
}