2014-01-19 6 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 클래스의 몇 가지 변경 사항을 mkaing하여 프로세스를 단순화하여 전역 로그 함수를 대신 호출 할 수 있습니다. 이는 로깅이 현재 어떻게 사용되고 있는지에 대한 광범위한 변경을 줄이거 나 없애줍니다.

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

매번 명시 적으로 '이름'을 전달하지 않는 방법이 있다고 생각합니까? – danijar

+0

아닙니다. 잠재적 인 모든 호출자가'Log' 인스턴스를 공유하게하려면 변수가 있어야합니다. * 어떻게 든 *, 누가 로그하고 있는지를 '로그'에 알려야합니다. – moswald

+0

아마,'module' 클래스에서'name'을 꺼내서 대신 매크로를 사용합니다. – moswald

관련 문제