我正在定义一个这样的类:
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_;
};
我将构造函数定义为:
void StaticRuntimeContext::Construct() {
std::ostream& test = cout;
stdout1_ = cout;
stdout2_ = cout;
//stdout3_ = NULL;
stderr_ = cerr;
}
我无法理解为什么将cout分配给test(std :: ostream&)可以编译,但编译器会为其余部分生成错误消息,如“stdout1_ = cout”。错误消息是:
/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
我想知道如何正确地将cout分配给这些ostream引用变量。谢谢!
答案 0 :(得分:6)
这是因为引用具有值语义,而operator =正在复制对象而不是分配新的引用。
您应该定义静态指针,在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_;
void StaticRuntimeContext::Construct() {
stdout1_ = &cout;
stdout2_ = &cout;
stdout3_ = &cout;
stderr_ = &cerr;
}
编辑: 并且您必须在.cpp文件中添加它
std::ostream* StaticRuntimeContext::stdout1_ = NULL;
std::ostream* StaticRuntimeContext::stdout2_ = NULL;
std::ostream* StaticRuntimeContext::stdout3_ = NULL;
std::ostream* StaticRuntimeContext::stderr_ = NULL;
答案 1 :(得分:1)
此代码
std::ostream& test = cout;
不是作业,而是新参考的构造。它也可以写成
std::ostream& test(cout);
没有等号。效果是一样的。
创建引用后无法反弹,因此必须在创建时将其设置为其值。静态成员也必须在某处定义,就像在相应的.cpp文件中一样。只需在那里设置值:
std::ostream& StaticRuntimeContext::stdout1_ = std::cout;
std::ostream& StaticRuntimeContext::stdout2_ = std::cout;
std::ostream& StaticRuntimeContext::stdout3_ = std::clog;
std::ostream& StaticRuntimeContext::stderr_ = std::cerr;
答案 2 :(得分:0)
在C ++中,参数变量在声明时必须初始化。
有效的:
int x;
int& foo = x;
无效:
int x;
int& foo;
foo = x;
答案 3 :(得分:0)
您需要使用指针,因为引用不允许重新绑定,std::ostream
是不可复制的。
答案 4 :(得分:0)
我无法理解为什么将cout分配给test(std :: ostream&)可以编译
因为不是作业;它是初始化。