Как закрыть/открыть поток (файловый и/или ввода/вывода) при новом обращении к объекту?

Создал класс:

#include <iomanip>
#include <thread>
#include <ctime>
#include <fstream>
#include <string>
#include "log.h"

std::time_t t = std::time(nullptr);
std::tm tm = *std::localtime(&t);

Logger* Logger::m_pThis = nullptr;
std::ofstream Logger::m_Logfile;
std::string Logger::prefix;

std::string Logger::logLevel = "INFO";

Logger::Logger(){}

Logger::~Logger()
{
    if(m_Logfile.is_open()){
        m_Logfile << std::endl;
        m_Logfile.close();
    }
    else{
        std::cout << std::endl;
    }
}

Logger::Logger(const Logger&){}

Logger Logger::getLogger()
{
    if (m_pThis == nullptr){
        m_pThis = new Logger();
        //std::cout << std::put_time(&tm, "%c") << "; " << m_pThis->logLevel << "; " << m_pThis->prefix << "(" << std::this_thread::get_id() << "): ";

    }
    return *m_pThis;
}

Logger Logger::getLogger(std::string fName)
{
    if (m_pThis == nullptr){
        m_pThis = new Logger();
        if (!fName.empty()){
            m_Logfile.open(fName, std::ios::app);
            //m_Logfile << std::put_time(&tm, "%c") << "; " << m_pThis->logLevel << "; " << m_pThis->prefix << "(" << std::this_thread::get_id() << "): ";
        }
    }
    return *m_pThis;
}

Logger Logger::getLogger(std::string fName, std::string prefixName)
{
    if (m_pThis == nullptr){
        m_pThis = new Logger();
        if (!fName.empty()){
            m_Logfile.open(fName, std::ios::app);
        }
        m_pThis->prefix = prefixName;
        //m_Logfile << std::put_time(&tm, "%c") << "; " << m_pThis->logLevel << "; " << m_pThis->prefix << "(" << std::this_thread::get_id() << "): ";
    }
    return *m_pThis;
}


Logger& Logger::operator<<(const std::string& sMessage)
{
    if(m_Logfile.is_open()) {
        m_Logfile << std::put_time(&tm, "%c") << "; " << this->logLevel << "; " << this->prefix << "(" << std::this_thread::get_id() << "): ";
        m_Logfile << sMessage << "\n";
    }
    else{
        std::cout << std::put_time(&tm, "%c") << "; " << this->logLevel << "; " << this->prefix << "(" << std::this_thread::get_id() << "): ";
        std::cout << sMessage << "\n";
    }


   return *this;
}

/*
Operator << for DOUBLE
*/
Logger& Logger::operator<<(const double& sDouble)
{
    std::string sString = std::to_string(sDouble);

    if(m_Logfile.is_open()) {
        m_Logfile << std::put_time(&tm, "%c") << "; " << this->logLevel << "; " << this->prefix << "(" << std::this_thread::get_id() << "): ";
        m_Logfile << sString;
    }
    else{
        std::cout << std::put_time(&tm, "%c") << "; " << this->logLevel << "; " << this->prefix << "(" << std::this_thread::get_id() << "): ";
        std::cout << sString;
    }


   return *this;
}


Logger& Logger::operator()(typelog type)
{
    switch(type)
    {
        case DEBUG: this->logLevel = "DEBUG"; break;
        case WARNING: this->logLevel = "WARNING"; break;
        case ERROR: this->logLevel = "ERROR"; break;
        default: this->logLevel = "INFO"; break;
    }
    Logger* new_pThis = new Logger(*this);
   return *new_pThis;
}

Запись в поток происходит оператором <<. Если в функции main вызвать

auto logger = Logger::getLogger("log.txt", "f2"); 
    logger(DEBUG) << "Running a thread";

    double timeSpent = 10.0;
    logger(WARNING) << "Time spent in the thread: " << timeSpent << " seconds";

то запись в файл выполнится 4 раза (при каждом вызове оператора <<). Как сделать так, чтобы запись в файл(файловый поток) происходила только при обращении к экземпляру класса (в примере это 2 раза: 1) при вызове logger(DEBUG) << "Running a thread"; и при вызове logger(WARNING) << "Time spent in the thread: " << timeSpent << " seconds";) ?


Ответы (0 шт):