#include <cstdlib>
#include <fstream>
#include <sstream>
#include <iostream>
struct Lock
{
virtual ~Lock() { }
virtual void lock() { }
virtual void unlock() { }
};
class DebugLogger
{
public:
DebugLogger(const char * filename, Lock & locker);
~DebugLogger();
template <typename T>
std::ostream & operator << (const T & obj);
std::ostream & operator <<
(std::ostream & (*func) (std::ostream &));
private:
DebugLogger(const DebugLogger &);
DebugLogger & operator = (const DebugLogger &);
private:
std::ofstream m_file;
std::ostringstream m_cache;
Lock & m_locker;
};
DebugLogger::DebugLogger(const char * filename, Lock & locker)
: m_file(filename, std::ios::app), m_locker(locker)
{
if (!m_file)
{
std::cerr << "open " << filename << " failed!" << std::endl;
exit(1);
}
}
DebugLogger::~DebugLogger()
{
if (m_file)
{
m_locker.lock();
m_file << std::endl << m_cache.str() << std::endl;
m_file.close();
m_locker.unlock();
}
}
template <typename T>
std::ostream & DebugLogger::operator << (const T & obj)
{
return(m_cache << obj);
}
std::ostream & DebugLogger::operator <<
(std::ostream & (*func) (std::ostream &))
{
return((*func)(m_cache));
}
static Lock s_lk;
static DebugLogger s_log("log.txt", s_lk);
int sum(int n)
{
s_log << "get sum( " << n << " )" << std::endl;
int result = 0;
for (int i = 1; i <= n; ++i)
{
result += i;
s_log << "i = " << i << ", sum = " << result << std::endl;
}
s_log << "sum ( " << n << " ) = " << result << std::endl;
return(result);
}
int main(int argc, char * argv[])
{
std::cout << sum(5) << std::endl;
return(0);
}
本来想在第二个operator << ()中,将内容刷新进日志(虽然可以用稍麻烦些的办法做到),但发现ostringstream没有清除自身内容的成员函数,用swap也行不通,干脆算了。