2009-08-18 64 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