2010-12-30 2 views
5

私のアプリケーションのログ・ファイルを書き込むために、C++でクラスを持っています。 Iすでにクラスを構築し、それが動作しますが、それはこのようなものですしている:まあ、ロガーのオブジェクトのために、ログファイルに行を印刷するために、それは単純である、という直感的であるCoutのような表記でC++でログ・ストリームを管理する

class Logger { 
    std::string _filename; 
public: 
    void print(std::string tobeprinted); 
} 

以下を行うために必要なもの:

Logger mylogger("myfile.log"); 
mylogger.print(std::string("This is a log line")); 

よく。方法のアプローチを使用することは、より良いパターンを使用するのと同じではありません< <です。 私は次のことをしたいと思います:

Logger mylogger("myfile.log"); 
mylogger << "This is a log line"; 

それだけです。私は< <演算子をオーバーロードしなければならないとし...しかし、この署名を使用してのオーバーロード(クラシック1):

ostream& operator<<(ostream& output, const MyObj& o); 

しかし、私はのostreamを持っていない... だから、次のように私はいいですか?

Logger& operator<<(Logger& output, const std::string& o); 

これは正しいですか? ありがとう

+0

'std :: ofstream'にはない機能は何ですか? –

+0

私は既にログクラスにすべての機能を持っています。ここでは、<< operatorを使うようなものをもっとC++にする方法が必要でした。 – Andry

+0

あなたはどんな機能を提供していますか? –

答えて

1

はい、これは正しい方法です。しかし、ログに記録する必要のあるすべてのデータ型について、< <演算子オーバーロードを追加する必要があります。

+0

ああもちろんもちろん – Andry

+0

ああ、もう1つ質問sory、もし私が次のことをすることができます:私はchar *を使うことができます:Logger&operator <<(Logger&output、const char * o)? – Andry

+1

基本的な実装で標準のioストリームを使用する場合は、それぞれのタイプに対してオーバーロードする必要はありません。単純に 'operator <<'をテンプレートすれば正常に動作します。 – Nim

4

Loggerを単にstd :: ostreamまたはstd :: ostringstreamのサブクラスにしないのはなぜですか?その後、そのすべての機能が既に実装されています。

+0

はい、正しい方法です...私のケースでは、私は過度の問題に苦しんでいると思います...はい、私はすべての機能を持っていますが、それらの多くは私にとって役に立たないでしょう...ちょうど何らかの種類のラッパーが必要です。ただ1つの方法だけが私の興味です。それ以上のことはありません。 – Andry

+0

+1:この機能は既に存在しています。 – Puppy

+0

'ostream'や' ostringstream'には多くの仮想関数がありませんので、 'ostream'や' ostringstream'にはない機能をどのように拡張したり強化したりするのかがわかりません。 –

6
class Log 
{ 
public: 

    enum Level { Debug, Error, Info }; 

    static ostream& GetStream() { return cout; } 
    static bool IsLevelActive(Level l) { return true; } 
}; 

#ifndef NO_LOG 
#define LOG_ERROR(M) do { if (Log::IsLevelActive(Log::Error)) (Log::GetStream() << "ERR: " << M << "\n"); } while (false) 
#define LOG_INFO(M) do { if (Log::IsLevelActive(Log::Info)) (Log::GetStream() << "INF: " << M << "\n"); } while (false) 
#define LOG_WARNING(M) do { if (Log::IsLevelActive(Log::Warning)) (Log::GetStream() << "WRN: " << M << "\n"); } while (false) 
#else 
#define LOG_ERROR(M) 
#define LOG_INFO(M) 
#define LOG_WARNING(M) 
#endif 

struct MyObject { 
    int a, b; 
}; 

ostream& operator<<(ostream& ostr, const MyObject& obj) { 
    ostr << "(a=" << obj.a << ", b=" << obj.b << ")"; 
    return ostr; 
} 

void test() { 
    int v1 = 42; 
    int v2 = 43; 
    LOG_INFO("value1=" << v1 << ", value2=" << v2); 

    MyObject o = {1, 2}; 
    LOG_INFO("obj=" << o); 
} 
+0

ああ....いいです...それは確かに物事を行う別の方法です...ありがとうrolo。 – Andry

0

すべてのストリーム演算子を再定義する必要があるため、新しいストリームを完全に作成する必要はありません。データが文字データに変換される方法を完全に変更したい場合にのみこれを実行します。 (Ick)。

私が見つけたのは、ストリームを追跡し、その内容を破壊したときに自分が選択した場所(ロガー)に送信するクラスを作成することです。これは、マクロのばらつきと組み合わせて、あなたが探しているものを提供します:ロギングのためのストリーム構文。

ブーストには、実際にこれを助けるいくつかのクラスがあります。 iostreamsを見てください。

関連する問題