一个班级怎么知道谁叫它的方法?

时间:2014-01-19 15:25:34

标签: c++ methods global state

目前,我为每个使用它的代码创建了一个新类实例。构造函数采用字符串名称,因此我知道在类中调用我的方法。

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;
};

此示例类由一系列模块使用,这些模块派生自抽象类型。

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!"

但是现在,我希望为所有模块共享Log的相同实例。我怎么能这样做,仍然与方法调用的来源不同?

背景:有很多模块,他们使用两种类型。首先,在模块之间共享全局的经理。其次,为每个模块单独创建的助手(例如上面的示例类)。但我希望找到一个简单设计的单一抽象。考虑一个日志助手,它应该以不同的,均匀分布的颜色为不同模块的消息着色。这样的帮助者需要在所有模块之间共享状态。

2 个答案:

答案 0 :(得分:2)

您可以通过对Log类进行一些更改来简化该过程,以使其调用全局日志函数。这减少或消除了当前使用日志记录的方式的广泛变化。

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;
};

您可以继续动态分配Log对象的实例,也可以使用合成。

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!");
    }
};

答案 1 :(得分:1)

我想我明白你的想法。试试这个:

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();

您的记录器必须更改为接受其Print成员中的呼叫者姓名。