I'm defining a class like this:
class StaticRuntimeContext {
public:
enum Verbosity {
kHIGH,
kMEDIUM,
kLOW,
kSILENT
};
static void Construct();
static std::ostream& stdout1() {return stdout1_;}
static std::ostream& stdout2() {return stdout2_;}
static std::ostream& stdout3() {return stdout3_;}
static std::ostream& stderr() {return stderr_;}
protected:
private:
static std::ostream& stdout1_;
static std::ostream& stdout2_;
static std::ostream& stdout3_;
static std::ostream& stderr_;
};
I'm defining the construct function as:
void StaticRuntimeContext::Construct() {
std::ostream& test = cout;
stdout1_ = cout;
stdout2_ = cout;
//stdout3_ = NULL;
stderr_ = cerr;
}
I cannot understand why assigning cout to test (std::ostream&) is OK to compile but the compiler produces error messages for the rest like "stdout1_=cout". The error message is:
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/ios_base.h:791:5: error: ‘std::ios_base& std::ios_base::operator=(const std::ios_base&)’ is private
I'm wondering what I should do to correctly assign cout to these ostream reference variables. Thanks!
It's because references have value semantics, and the operator = is copying the object instead of assigning a new reference.
Instead of references you should define static pointers, assign them in Construct, and return references in your accessors
static std::ostream& stdout1() {return *stdout1_;}
static std::ostream& stdout2() {return *stdout2_;}
static std::ostream& stdout3() {return *stdout3_;}
static std::ostream& stderr() {return *stderr_;}
protected:
private:
static std::ostream* stdout1_;
static std::ostream* stdout2_;
static std::ostream* stdout3_;
static std::ostream* stderr_;
void StaticRuntimeContext::Construct() {
stdout1_ = &cout;
stdout2_ = &cout;
stdout3_ = &cout;
stderr_ = &cerr;
}
EDIT: And you must add this in your .cpp file
std::ostream* StaticRuntimeContext::stdout1_ = NULL;
std::ostream* StaticRuntimeContext::stdout2_ = NULL;
std::ostream* StaticRuntimeContext::stdout3_ = NULL;
std::ostream* StaticRuntimeContext::stderr_ = NULL;
This code
std::ostream& test = cout;
is not an assignment, but a construction of a new reference. It can also be written
std::ostream& test(cout);
without the equal sign. The effect is the same.
A reference cannot be rebound once it is created, so it must be set to its value when created. The static members also have to be defined somewhere, like in the corresponding .cpp file. Just set the values there:
std::ostream& StaticRuntimeContext::stdout1_ = std::cout;
std::ostream& StaticRuntimeContext::stdout2_ = std::cout;
std::ostream& StaticRuntimeContext::stdout3_ = std::clog;
std::ostream& StaticRuntimeContext::stderr_ = std::cerr;
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