Reputation: 313
I have read multiple questions and answers on that topic, but unfortunately none of them helped yet. I want to use the same debug file ouput in two classes A and B, where an instance of A creates an instance of B. I have something like:
class A {
public:
A() : debug("debug.txt") { };
private:
std::ofstream debug;
}
class B {
public:
B(std::ofstream &ofs) : debug(ofs) { };
private:
std::ofstream &debug;
}
and create an instance of it with
B *b = new B(debugUnderlying);
which works quite well. However, I now want to have an additional constructor to be able to use it without an ofstream. The object shall then open a new file. I got the point that, as I have a reference, I need to initialize it in the initialization list. I tried multiple things:
B() : debug() { debug.open("debug2.txt"); };
error: invalid initialization of non-const reference of type ‘std::ofstream& {aka std::basic_ofstream<char>&}’ from an rvalue of type ‘const char*’
or
B() : debug("debug2.txt") { };
error: value-initialization of reference type ‘std::ofstream& {aka std::basic_ofstream<char>&}’
or (quite clear, since I have a temporary object)
error: invalid initialization of non-const reference of type ‘std::ofstream& {aka std::basic_ofstream<char>&}’ from an rvalue of type ‘std::ofstream {aka std::basic_ofstream<char>}’
How can I do this? Thanks for any suggestions!
Upvotes: 1
Views: 1825
Reputation: 8313
to fix your error:
B():debug(*(new std::ofstream("debug.txt"))){}
But: if you do so I guess you'll forget to delete...
So:
You better use a singleton to wrap the debug object
class Debug{
std::ofstream debug;
//private ctor, you can't create an object for this class outside
Debug(const std::string& filename):debug(filename){}
public:
//only way tou use this class is to call this method
static Debug* Instance(){
//the one and only Debug object, created at first use:
static Debug theObj("debug.txt");
return &theObj;
}
//write method
std::ostream& outstream(){
return debug;
}
};
//just for simplicity of use:
#define dbgout Debug::Instance()->outstream()
you can also define the macro like this:
#ifdef DEBUG
#define dbgout Debug::Instance()->outstream()
#else
// a release version won't create the debug file...
#define dbgout //
#endif
now you can use it like this from anywhere in your code:
dbgout<<" put your " << "stream " <<" here ";
Upvotes: 0
Reputation:
You may store a pointer and flag ownership:
class B {
public:
B() : stream(new ...), owner(true) {}
B(std::ostream& s) : stream(&s), owner(false) {}
~B() { if(owner) delete stream; }
private:
std::ostream* stream;
bool owner;
};
Note: I replaced ofstream with ostream.
Upvotes: 2