Question

Currently I create a new instance of the class for each code that uses it. The constructor takes a string name, so I know inside the class, who called my methods.

class Log {
public:
    Log(std::string Name) : name(Name) {}
    void Print(std::string Message) {
        std::cout << name << " said " << Message << std::endl;
    }
private:
    std::string name;
};

This example class is used by a range of modules, which derive from an abstract type.

class Module {
public:
    Module(std::string Name) : log(new Log(Name)) {}
    virtual void Update() = 0;
private:
    Log *log;
};

class Renderer : public Module {
public:
    void Update() {
        log->Print("Hello World!");
    }
};

Renderer renderer("Renderer");
renderer.Update(); // "Renderer says Hello World!"

But now, I want to share the same instance of Log for all modules. How can I do this and still distinct from where method calls come from?

Background: There are plenty of modules and they make use of two types of classes. First, managers that are shared globally among modules. Second, helpers such as the example class above which are created separately for each module. But I want to find a single abstraction of both for a simpler design. Think of a logging helper that should color messages of different modules in different, evenly distributed, colors. Such a helper need to share state among all modules.

Était-ce utile?

La solution

You can simplify the process by mkaing a few changes to the Log class to have it call the global log functions instead. This reduce or eliminate extensive changes to how the logging is currently being used.

class Log {
public:
    explicit Log(const std::string& name) : name(name) {}
    void Print(const std::string& message) const {
        GlobalLogPrint(name, message);
    }

private:
    const std::string name;
};

You can continue to dynamically allocate instances of the Log object or you can use composition.

class Module {
public:
    explicit Module(const std::string& name) : log(name) {}
    virtual void Update() = 0;
protected:
    Log log;
};

class Renderer : public Module {
public:
    void Update() {
        log.Print("Hello World!");
    }
};

Autres conseils

I think I understand what you're wanting. Try this:

class Module
{
public:
    Module(std::string name) : name(name) {}
    void Update()
    {
        VUpdate(name);
    }

private:
    virtual void VUpdate(const std::string &name) = 0;

protected:
    static Log *log;

private:
    std::string name;
};

class Renderer : public Module
{
private:
    virtual void VUpdate(const std::string &name)
    {
        log->Print(name, "Hello World!");
    }
};

Log *Module::log = new Log();

Your logger will have to change to accept the name of the caller in its Print member.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top