6

次のような機能を備えたロガークラスを作成したいと思います。

Logger log;
log << "Error: " << value << "seen" << endl;

これにより、カスタム形式のメッセージが出力されます。例: 「12-09-2009 11:22:33 エラー 5 が表示されました」

私の単純なクラスは現在次のようになっています。

class Logger {
    private:
        ostringstream oss;
    public:
        template <typename T>
        Logger& operator<<(T a);
}

template <typename T>
Logger& Logger::operator<<(T a) {
    oss << a;
    return *this;
}

void functionTest(void) {
    Logger log;
    log << "Error: " << 5 << " seen";
}

これにより、oss は "Error: 5 seen" というバッファを正しく持つようになります。しかし、何かが画面に表示されるように、他にどの関数を作成/変更する必要があるのか​​ わかりません。これを機能させる方法を知っている人はいますか、またはこのクラスを設計して機能を機能させる別の方法はありますか?

4

5 に答える 5

4

every の後ろにstd::ostreamstreambuf. 経由で取得および設定できますstd::stream::rdbuf()。特に、ラップすることができます。ストリーミングされたテキストを後処理する streambuf オブジェクトを提供できます。(後処理とstd::cout << 123;は、 と区別できないことを意味しますstd::cout << "123";)

あなたの特定のケースでは、後処理はかなり単純です。すべての行の先頭に、いくつかのバイトを挿入します。これは単に、現在の行のプレフィックスを既に出力しているかどうかを追跡する必要があることを意味します。そうでない場合は、そうしてフラグを設定します。改行が表示されたら、いつでもリセットしてください。streambuf ラッパーには、単一boolの値の状態しかありません。

于 2010-02-10T09:49:57.340 に答える
1

コンパイル時の最適化で提案されている単純なロガーを確認してください-リリースバイナリからデバッグプリントを削除します。あなたのニーズには十分なはずです。Br、Gracjan

于 2013-02-06T18:17:16.540 に答える
1

私が見る限り、ロガーは ostringstream と同じです。与えられたものを取り、それを文字列ストリームに出力するだけです。このように使いたい場合は、文字列を cout に出力する Logger のデストラクタを記述できます。

Logger::~Logger()
{
    std::cout<<getcurrentDateTimeAsString()<<" "<<oss.str()<<std::endl;
}

しかしもちろん、Logger* が作成され、プログラム全体で使用されている場合、これは意味がありません。

于 2010-02-10T09:15:40.533 に答える
1

問題は、情報をいつ、どのように同期するかを選択することです。したがって、バッファリングされているかどうかに関係なく、EOL とライン上の情報を制御する以外に選択肢はありません。それをフラッシュするか、直接出力します。

デストラクタが EOL/Flush として使用される場合でも、

{ log << [anything]; }ブラケットを終了するログのデストラクタを呼び出すインライン ローカル スタック ブラケット構文として、または std::endl として、いずれかを使用する必要があります。

「<<」や「+」などの追加演算子を使用してメタオブジェクトを実装しない限り、明示的な方法で行を終了したり、フラッシュしたりする必要があります。

于 2015-01-23T20:02:38.177 に答える
0

これは(この投稿から)あなたが望むことをしますが、各行を std::endl で終了することを強制します:

class Logger {
    private:
        ostringstream oss;
    public:
        template <typename T>
        Logger& operator<<(T a);

    Logger& operator<<( std::ostream&(*f)(std::ostream&) )
    {
        if( f == std::endl )
        {
            std::cout << "12-09-2009 11:22:33" << oss.str() << std::endl;   
            oss.str("");
        }
        return *this;
    }
};

template <typename T>
Logger& Logger::operator<<(T a) {
    oss << a;
    return *this;
}

void functionTest(void) {
    Logger log;
    log << "Error: " << 5 << " seen" << std::endl;
}

int main()
{
    functionTest();
}

編集:あなたのコメントによると、それはあなたが望むものではないようです。次に、MSalters が言うようにすることをお勧めします。

于 2010-02-10T09:19:48.187 に答える