我应该如何正确地将cout分配给静态ostream引用变量?

时间:2011-11-09 19:34:14

标签: c++ iostream ostream

我正在定义一个这样的类:

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引用变量。谢谢!

5 个答案:

答案 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&)可以编译

因为不是作业;它是初始化。

相关问题