Я пытаюсь создать каркас для ведения журналов в c ++, но информация не передается субкомпонентам регистратора, что я делаю неправильно? - PullRequest
0 голосов
/ 01 октября 2019

вот мой код, когда я пытаюсь запустить его, main выводит информацию, помещенную в LoggerComponent, но не сам Logger. Я не знаю почему, что может помешать регистратору передавать информацию в базовый компонент регистратора?

Я пытался использовать информацию из http://www.cplusplus.com/reference/map/map/ и https://www.geeksforgeeks.org/map-associative-containers-the-c-standard-template-library-stl/

регистратор.cpp:

#include "logger.hpp"

Logger::Logger(bool verbose, bool fileoutput)
{
    if(verbose)
    {
        LoggerComponent c1(LoggerLevel::DEBUG, &std::cout);
        addLogger (LoggerType::CONSOLE, &c1);
        c1.output (LoggerLevel::DEBUG, "This is the start of console output");
    }
    if(fileoutput)
    {

    }
}

void Logger::output(LoggerLevel level, std::string message)
{
    for(auto& x : components)
    {
        x.second->output (level, message);
    }
}

void Logger::addLogger(LoggerType type, LoggerComponent* component)
{
    if(components.find (type) == components.end ())
        components.emplace(type, component);
}

LoggerComponent* Logger::getLogger (LoggerType type)
{
    if(components.find (type) != components.end ())
        return components.at (type);
    return nullptr;
}

void Logger::clearLoggers()
{
    components.clear ();
}

void Logger::removeLogger(LoggerType type)
{
    if(components.find (type) != components.end ())
        components.erase (type);
}

logger.hpp

#ifndef LOGGER_HPP
#define LOGGER_HPP

#include "loggercomponent.hpp"

#include <map>

enum class LoggerType
{
    CONSOLE,
    FILE
};

class Logger
{
public:
    explicit Logger(bool verbose, bool fileoutput);

    void output(LoggerLevel level, std::string message);

    void addLogger(LoggerType type, LoggerComponent* component);
    void removeLogger(LoggerType type);
    void clearLoggers();
    LoggerComponent* getLogger(LoggerType type);

private:
    std::map<LoggerType, LoggerComponent*> components;
};

#endif // LOGGER_HPP

main.cpp

#include "logger.hpp"

int main()
{
    int* p;
    int i = 5;
    int j = 5;
    p = &i;
    std::cout << p << std::endl;
    p = &j;
    std::cout << p << std::endl;

    LoggerComponent c(LoggerLevel::DEBUG, &std::cout);

    c.output (LoggerLevel::INFO, "Hello World!");
    c.output (LoggerLevel::CRITICAL, "Hello World!");

    Logger c2(true, true);

    std::cout << c.getOutputStream () << std::endl;
    std::cout << c2.getLogger (LoggerType::CONSOLE)->getOutputStream () << std::endl;

    c2.output (LoggerLevel::INFO, "Hello World!");
    c2.output (LoggerLevel::CRITICAL, "Hello World!");
}

loggercomponent.hpp

#ifndef LOGGERCOMPONENT_HPP
#define LOGGERCOMPONENT_HPP

#include <iostream>
#include <string>
#include <ctime>

enum class LoggerLevel
{
    INFO,
    DEBUG,
    WARNING,
    ERROR,
    CRITICAL
};

class LoggerComponent
{
public:
    explicit LoggerComponent(LoggerLevel level, std::ostream* output);

    LoggerLevel getMinimumLevel();
    std::ostream* getOutputStream();
    void setMinimumLevel(LoggerLevel level);
    void setOutputStream(std::ostream* output);

    void output(LoggerLevel level, std::string outputMessage);

private:
    std::string getLevelString(LoggerLevel level);

    LoggerLevel minimumLevel;
    std::ostream* outputStream;
};

#endif // LOGGERCOMPONENT_HPP

loggercomponent. cpp

#include "loggercomponent.hpp"

LoggerComponent::LoggerComponent(LoggerLevel level,
                                 std::ostream* output)
{
    setMinimumLevel (level);
    setOutputStream (output);
}

void LoggerComponent::setMinimumLevel(LoggerLevel level)
{
    if(minimumLevel != level)
        minimumLevel = level;
}

void LoggerComponent::setOutputStream(std::ostream *output)
{
    if(outputStream != output)
        outputStream = output;
}

LoggerLevel LoggerComponent::getMinimumLevel()
{
    return minimumLevel;
}

std::ostream* LoggerComponent::getOutputStream()
{
    return outputStream;
}

std::string LoggerComponent::getLevelString(LoggerLevel level)
{
    switch (level) {
    case LoggerLevel::INFO:
        return "INFO";
    case LoggerLevel::DEBUG:
        return "DEBUG";
    case LoggerLevel::WARNING:
        return "WARNING";
    case LoggerLevel::ERROR:
        return "ERROR";
    case LoggerLevel::CRITICAL:
        return "CRITICAL";
    }
    return nullptr;
}

void LoggerComponent::output(LoggerLevel level, std::string outputMessage)
{
    if(level >= minimumLevel)
    {
        time_t now = time(nullptr);
        *outputStream << ctime(&now)
                      << (getLevelString (level) + " >> " + outputMessage)
                      << std::endl << std::endl;
    }
}

вывод:

0x60fda8 0x60fdac вт 01 окт. 12:29:14 2019 КРИТИЧЕСКИЙ >> Hello World!

вт 01 окт. 12:29:14 2019DEBUG >> Это начало вывода на консоль

0x6fd0cd00 0x60fdb0

1 Ответ

3 голосов
/ 01 октября 2019

Вы храните указатель на объект, локальный для конструктора (c1) в components. Он будет уничтожен, а указатель будет недействительным, если вы попытаетесь использовать его позже.

Сохраните сам объект (или std::unique_ptr, если у вас есть веские основания не хранить сам объект) на карте. вместо этого.

...