I have a class in c++ in order to write log files for an application of mine. I have already built the class and it works, it is something like this:
class Logger {
std::string _filename;
public:
void print(std::string tobeprinted);
}
Well, it is intuitive that, in order to print a line in the log file, for an object of Logger, it is simply necessary to do the following:
Logger mylogger("myfile.log");
mylogger.print(std::string("This is a log line"));
Well. Using a method approach is not the same as using a much better pattern like << is. I would like to do the following:
Logger mylogger("myfile.log");
mylogger << "This is a log line";
That's all. I suppose I must overload the << operator... But overloading using this signature (the classic one):
ostream& operator<<(ostream& output, const MyObj& o);
But I do not have a ostream... So, should I do as follows?
Logger& operator<<(Logger& output, const std::string& o);
Is this the right way? Thanks
The C++ compiler has two very useful defines for logging: the __FILE__ and __LINE__ defines, which contain the name of the file and the line in which they are placed and can help you track down the location of the error. Because I am using the compiler define, they are automatically inserted into the correct place.
The cout object in C++ is an object of class ostream. It is defined in iostream header file. It is used to display the output to the standard output device i.e. monitor. It is associated with the standard C output stream stdout.
cout is an object of the output stream that is used to show output. Basically, cin is an input statement while cout is an output statement. They also use different operators. cin uses the insertion operator( >> ) while cout uses the extraction operator( << ).
class Log
{
public:
enum Level { Debug, Error, Info };
static ostream& GetStream() { return cout; }
static bool IsLevelActive(Level l) { return true; }
};
#ifndef NO_LOG
#define LOG_ERROR(M) do { if (Log::IsLevelActive(Log::Error)) (Log::GetStream() << "ERR: " << M << "\n"); } while (false)
#define LOG_INFO(M) do { if (Log::IsLevelActive(Log::Info)) (Log::GetStream() << "INF: " << M << "\n"); } while (false)
#define LOG_WARNING(M) do { if (Log::IsLevelActive(Log::Warning)) (Log::GetStream() << "WRN: " << M << "\n"); } while (false)
#else
#define LOG_ERROR(M)
#define LOG_INFO(M)
#define LOG_WARNING(M)
#endif
struct MyObject {
int a, b;
};
ostream& operator<<(ostream& ostr, const MyObject& obj) {
ostr << "(a=" << obj.a << ", b=" << obj.b << ")";
return ostr;
}
void test() {
int v1 = 42;
int v2 = 43;
LOG_INFO("value1=" << v1 << ", value2=" << v2);
MyObject o = {1, 2};
LOG_INFO("obj=" << o);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With