2011-12-09 4 views
8

로깅에 사용되는 스트림을 보유하고 싶은 C++ 클래스가 있습니다.C++ 스트림을 멤버 변수로 사용

스트림 오브젝트의 구성 후에 세트 (그리고 아마도 리셋) 할 수 있어야한다.

스트림을 std::cout으로 설정하거나 파일에 기록 할 파일 스트림 또는 데이터를 무시하는 것 이상의 아무것도 수행하지 않는 문자열 스트림 (예 : /dev/null)으로 설정할 수 있어야합니다. 어쨌든 객체 유형은 ostream이어야하며 객체 작성자는 언제든지 재설정 할 수 있습니다. 클래스 자체는 구체적인 스트림 유형을 알지 못합니다.

내가 ostream에 대한 포인터와 함께이 작업을 수행 할 수 있지만 다음 구문이 DEREF 연산자를 사용하는 데, 약간 성가신된다 :

(*m_log) << "message"; 

보다는

m_log << "message"; 

을하지만 내가 할 수있는 스트림 객체는 객체가 초기화 된 후에 재설정 될 필요가 있기 때문에 참조를 사용하지 않는다.

건설 후 재설정 할 수 여전히 즉, 포인터를 사용하지 않도록,이를하지만,하는 우아한 방법이 있나요?

+2

에 살고 참조? ostream & mlog() {return * m_log;}의 과정을 따라 가십시오. 다음과 같이 작성하십시오 : mlog() << "message"; – fjardon

+0

포인터를 사용하여'std :: ostream & o = * m_log;'함수로 시작하십시오. –

+2

@ fjardon : 왜 작은 대답으로 제공하지 않습니까? ; P – Xeo

답변

9

당신은 스트림을 재설정 할 수 있습니다 : 당신이 당신의 스트림에 대한 참조를 반환 작은 멤버 함수를 제공하지 않는 이유는 무엇 https://ideone.com/Ci4eo

#include <fstream> 
#include <iostream> 
#include <string> 

struct Logger 
{ 
    Logger(std::ostream& os) : m_log(os.rdbuf()) { } 

    std::streambuf* reset(std::ostream& os) 
    { 
     return m_log.rdbuf(os.rdbuf()); 
    } 

    template <typename T> friend Logger& operator<<(Logger& os, const T& t) 
    { os.m_log << t; return os; } 

    friend Logger& operator<<(Logger& os, std::ostream& (*pf)(std::ostream&)) 
    { os.m_log << pf; return os; } 

    private: 
    std::ostream m_log; 
}; 

int main(int argc, const char *argv[]) 
{ 
    Logger logto(std::cout); 

    logto << "Hello world" << std::endl; 

    logto.reset(std::cerr); 
    logto << "Error world" << std::endl; 

    return 0; 
} 
+0

이것은 제가 찾고있는 라인을 따라 멋진 솔루션입니다 에 대한. 예를 들어 T를 만드는 등의 두 번째 스트림을 (선택적으로) 추가 할 수 있도록 확장 할 수 있습니다. 충분히 평판을 얻으면이 점을 개선 할 것입니다. (: 감사합니다. –

+0

Tee-stream과 같은 시설을 찾으려면 [Boost Iostreams] (http://www.boost.org/doc/libs/1_48_0/libs/iostreams/doc/index)를보십시오. html? path = 1), 예를 들어 [Tee Filter] (http://www.boost.org/doc/libs/1_48_0/libs/iostreams/doc/functions/tee.html#tee_filter)와 [Pipelines] (http://www.boost.org/doc/libs/1_48_0/libs/iostreams/doc/guide/pipelines.html) – sehe

4

왜 스스로 문제가 있습니까?

class foo{ 
public: 
    // .. 
private: 
    std::ostream& log() const{ return *m_log; } 
    mutable std::ostream* m_log; 
}; 

대신 log() << "blah\n";을 사용하십시오.

+1

당신은 물론 함수에서'return * m_log; '를 의미합니다. –

+1

@James : 무슨 뜻인지 모르겠다. ♪ – Xeo

+0

방금 ​​페이지를 새로 고치기 전에 로그 방법에 *가 없었습니다. –

관련 문제