首先,我不太确定你的意思是什么是cout
-like 对象?也许一个std::ostream
.
无论如何,这样做的通常方法是使用过滤流缓冲区。除了通常的位置之外,只需编写一个转发到日志文件的 streambuf,然后将其插入到您想要的任何位置:
class LoggingOutputStreambuf : public std::streambuf
{
std::streambuf* myDest;
std::ofstreambuf myLogFile;
std::ostream* myOwner;
protected:
int overflow( int ch )
{
myLogFile.sputc( ch ); // ignores errors...
return myDest->sputc( ch );
}
public:
LoggingOutputStreambuf(
std::streambuf* dest,
std::string const& logfileName )
: myDest( dest )
, myLogFile( logfileName.c_str(), std::ios_base::out )
, myOwner( nullptr )
{
if ( !myLogFile.is_open() ) {
// Some error handling...
}
}
LoggingOutputStreambuf(
std::ostream& dest,
std::string const& logfileName )
: LoggingOutputStreambuf( dest.rdbuf(), logfileName )
{
dest.rdbuf( this );
myOwner = &dest;
}
~LoggingOutputStreambuf()
{
if ( myOwner != nullptr ) {
myOwner->rdbuf( myDest );
}
}
};
(这是 C++11,但为 C++03 修改它应该不难。)
要使用,您可以使用以下内容:
LoggingOutputStreambuf logger( std::cout );
// ...
所有输出都std::cout
将被记录,直到logger
超出范围。
在实践中,您可能会使用比 a 更复杂的东西
filebuf
来记录日志,因为您可能希望在每行的开头插入时间戳,或者在每行的末尾系统地刷新。(过滤流缓冲区也可以解决这些问题。)