Reputation: 67
beginner here
I am trying to make a "logger" for my c++ learning project, I´ve already set up code to manage the logging itself, but I can´t get the function to work from other classes.
Here´s my "Debugger" class
class MSEdebug
{
MSEdebug(){logOutput.open("log.txt");}
~MSEdebug() { logOutput.close(); }
void debuglog(std::string info)
{
#ifdef DEBUG
std::cout << "LOG:" << info << std::endl;
#endif // DEBUG
logOutput << "LOG:" << info << "\n";
}
std::ofstream logOutput;
};
And here´s what I want to be able to do:
#include "MSE_debug.h"
//...
MSEapp::debugTest()
{
MSEdebug::debuglog("Test, 1, 2, 3...");
}
Now this doesn´t work, and you experienced C++ programmers are probably rolling your eyes already, but could you be so kind to tell me how I would get it to work.
Btw, I hope I´ve done this correctly, this is my first question, so I´m sorry if it´s bad
Upvotes: 3
Views: 152
Reputation: 149125
The canonical way is to use the singleton pattern to have a unique instance of the class MSEDebug
that is easily accessible.
class MSEdebug
{
MSEdebug(){logOutput.open("log.txt");}
public:
~MSEdebug() { logOutput.close(); }
void debuglog(std::string info)
{
#ifdef DEBUG
std::cout << "LOG:" << info << std::endl;
#endif // DEBUG
logOutput << "LOG:" << info << "\n";
}
static MSEdebug& getInstance() {
static MSEdebug instance;
return instance;
}
private:
std::ofstream logOutput;
};
You can then use it that way:
MSEdebug::getInstance().debuglog("Test, 1, 2, 3...");
Upvotes: 3
Reputation: 20586
Yes. You need to use a static function. Here is some code to get you started.
class MSEdebug
{
public:
MSEdebug(){}
~MSEdebug() { logOutput.close(); }
static void debuglog(std::string info)
{
#ifdef DEBUG
std::cout << "LOG:" << info << std::endl;
#endif // DEBUG
if( ! logOutput.is_open() )
{
//first use - open logfile
logOutput.open("log.txt");
}
logOutput << "LOG:" << info << "\n";
}
static std::ofstream logOutput;
};
You will have to construct logOutput somewhere in a .cpp file
std::ofstream MSEdebug::logOutput;
BTW someone suggested "you need an actual variable of type MSEdebug". This is wrong. If you do it that way, each time you construct an "actual variable" the class will try to open another copy of the log file.
Upvotes: -1
Reputation: 39404
This might be the one case where a singleton might be in order:
class MSEdebug {
private:
MSEdebug(){ logOutput.open("log.txt"); }
~MSEdebug() { logOutput.close(); }
public:
static MSEdebug& instance(){
static MSEdebug debug;
return debug;
}
void debuglog(std::string info) {
#ifdef DEBUG
std::cout << "LOG:" << info << '\n';
#endif // DEBUG
logOutput << "LOG:" << info << '\n';
}
private:
std::ofstream logOutput;
};
Usage like this:
#include "MSE_debug.h"
//...
MSEapp::debugTest()
{
MSEdebug::instance().debuglog("Test, 1, 2, 3...");
}
Upvotes: 4