2014-01-19 106 views
0

目前,我爲每個使用它的代碼創建一個類的新實例。構造函數接受一個字符串名稱,所以我知道在類內調用了我的方法。一個班級如何知道誰調用了它的方法?

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同一實例所有模塊。我怎樣才能做到這一點,仍然與方法調用的來源不同?

背景:有很多模塊,他們使用兩種類型。首先,模塊之間全球共享的管理人員。其次,助手,比如上面的示例類,它是爲每個模塊分別創建的。但我想爲簡單的設計找到一個簡單的抽象。想想一個日誌助手,它應該以不同的,均勻分佈的顏色爲不同模塊的消息着色。這樣的幫手需要在所有模塊之間共享狀態。

+0

這不是一個好主意,但你可以試試這個:http://www.gnu.org/software/libc/manual/html_node/Backtraces.html – tumdum

+0

你不能。出於這個原因,我們使用訪問修飾符。 –

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

是否有可能將Log類嵌入到全局? – danijar

+0

只有當您更改'Log'類不調用全局函數時,否則最終會產生循環依賴性。 –

+0

我[得到這個工作](http://ideone.com/csNMx5)。非常感謝。 – danijar

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成員接受呼叫者的姓名。

+0

您是否認爲每次都沒有明確地傳遞'name'的方法? – danijar

+0

不是。如果你希望'Log'實例被所有可能的調用者共享,那麼它必須是可變的。 *不知何故*,必須告訴「日誌」誰正在撥打電話。 – moswald

+0

也許,我會從'Module'類中取出'name',而只是使用宏。 – moswald

相關問題