2009-08-18 43 views
0

我正在將函數添加到我的(簡單)log class中,以使其像流一樣可用。 目前,一些修改後,我得到這個(在我CPP):如何獲取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; 
    } 

現在,在我的「客戶端」的應用程序,我使用此代碼檢查結果(m_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 2009-08-18 20:36:34

+0

是的,addText()會填充std :: stringstream,而logText()會做一些工作來「記錄」流的字符串結果。 logText()將字符串值寫入文件和標準流並添加一些時間信息,因此只有在調用logText()時才需要考慮「日誌」。如果文本爲空,則呼叫將被忽略。 – Klaim 2009-08-18 20:41:52

回答

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"; 
} 

在每個分號之後,Sublog的析構函數被稱爲


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 2009-08-18 21:34:22

+0

哇,使用臨時對象及其析構函數,沒有想到這一點。 +1 – Ozan 2009-08-18 21:47:38

+0

謝謝,它真的很好,只有一個小臨時對象! 我將編輯帖子以提供當前完整的解決方案,因爲有些細節必須修復。 – Klaim 2009-08-18 22:04:42