2011-12-09 11 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を作成するなど、2番目のストリームを(オプションで)追加するように拡張することができます。十分な評判があれば、これをアップレートします。 (:ありがとう。 –

+0

Tee-streamなどの施設を探しているなら、[Boost Iostreams](http://www.boost.org/doc/libs/1_48_0/libs/iostreams/doc/index)を見てください。 [Tee Filter](http://www.boost.org/doc/libs/1_48_0/libs/iostreams/doc/functions/tee.html#tee_filter)を[Pipelines]と組み合わせて使用​​すると、html?path = 1) (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

@ジェームズ:あなたが何を意味するか分かりません。 ♪ – Xeo

+0

ページをリフレッシュする前にログメソッドに*がありませんでした。 –

関連する問題