2009-08-18 15 views
0

自分の(シンプルな)log classに関数を追加して、ストリームのように使用できるようにします。 現在、いくつかの変更後、私は(私のCPPに)これを得た:私はあなたが既に持っているようm_logが有効なポインタである(結果を確認するために、このコードを使用していC++文字列ストリームの終わりを取得するには?

私の「クライアント」アプリで今
// blah blah blah... 
// note: here String is a defined as: typedef std::string String; 

void Log::logMessage(const String& message) 
    { 
     logText(); // to be sure we flush the current text if any (when "composing" a message) 
     addText(message); 
     logText(); // really log the message and make the current text empty 
    } 

// blah blah blah... 

    Log& operator<<(Log& log, const std::stringstream& message) 
    { 
     log.logMessage(message.str()); 
     return log; 
    } 

    Log& operator<<(Log& log, const String& message) 
    { 
     log.addText(message); 
     return log; 
    } 

)推測:

gcore::Log& log = *m_log; 
log << getName() << " : application created."; 
log << "This is a test for " << getName(); 

は、今私が得た問題は、このテストコードは、専用文字列で< <オペレータを呼び出しますのでlogText()(とLogMessageには)と呼ばれることはありませんということです。私は必要なもの は、文字列の指定した蒸気が終了したときlogText()を呼び出す方法です:

log << getName() << " : application created."; 

log.addText(getName()); 
log.addText(" : application create."); 
log.logText(); 

と同等になり、私もこれを行うか、するかどうかはわかりませんそれが可能ならば。私の最初の推測では、このようなストリームの終わりにはstd :: ENDLを使用することが可能であるということです。

log << getName() << " : application created." << std::endl; 

か何か同等、いることを、ストリームにオブジェクトを追加することなく、それを行うことが可能かどういいだろう。

+0

なぜログヘッダー内の

:私の場合は、このソリューションの(仕事と効果的)実装logText()が呼び出されるまで遅延して、実際にメッセージを記録しますか? – Ozan

+0

はい、addText()はstd :: stringstreamを満たしますが、logText()はストリームの文字列結果を「ログ」するためにいくつかの作業を行います。 logText()はファイルと標準ストリームに文字列値を書き込み、いくつかの時刻情報を追加するので、logText()が呼び出された後にのみ "log"を実行する必要があります。テキストが空の場合、呼び出しは無視されます。 – Klaim

答えて

3

あなたは一時オブジェクトを作成し、文の終わりをキャッチするために彼のデストラクタを使用することができます。

は、次のコードは、あなたにこの

のように使用される基本的な考え方

class Log 
{ 
public: 
    class Sublog 
    { 
    public: 
    Sublog(const std::string& message) 
    { 
     std::cout << message; 
    } 

    void addText(const std::string& message) 
    { 
     std::cout << message; 
    } 

    ~Sublog() 
    { 
     std::cout << std::endl; 
    } 

    Sublog& operator<<(const std::string& message) 
    { 
     this->addText(message); 
     return *this; 
    } 
    }; 

}; 

Log::Sublog operator<<(Log& log, const std::string& message) 
{ 
    return Log::Sublog(message); 
} 

を与える必要があります

int main() 
{ 
    Log log; 
    log << "Foo" << "bar"; 
    log << "baz" << "plop"; 
} 

各セミコロンの後に、サブログのデストラクタは

と呼ばれます。

Klaim:

/** To allow streaming semantic on logs (used in << operator) . 
*/ 
class LogStreamer 
{ 
public: 

    LogStreamer(Log& log, const String& text) 
     : m_log(log) 
    { 
     m_log.addText(text); 
    } 

    ~LogStreamer() 
    { 
     m_log.logText(); 
    } 

    LogStreamer& operator<<(const String& text) 
    { 
     m_log.addText(text); 
     return *this; 
    } 

private: 

    Log& m_log; 

}; 

GCORE_API LogStreamer operator<<(Log& log, const String& message); 

とCPPファイル内:

LogStreamer operator<<(Log& log, const String& message) 
{ 
    return LogStreamer(log, message); 
} 
+0

いい感じです、それを試してみましょう! – Klaim

+0

Wowは、一時的なオブジェクトとそのデストラクタを使って、それを考えませんでした。 +1 – Ozan

+0

おかげさまで、ちょっとした一時的なオブジェクトだけで本当に素敵な気分になりました! いくつかの詳細を修正しなければならないので、現在の完全なソリューションを提供するために投稿を編集します。 – Klaim

関連する問題