8

私はこのようなクラスを定義しています:

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;
}

テスト(std :: ostream&)にcoutを割り当ててもコンパイルしても問題ない理由がわかりませんが、コンパイラーは「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

これらのostream参照変数にcoutを正しく割り当てるにはどうすればよいのでしょうか。ありがとう!

4

5 に答える 5

10

これは、参照には値のセマンティクスがあり、演算子 = は新しい参照を割り当てる代わりにオブジェクトをコピーしているためです。

参照の代わりに、静的ポインターを定義し、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;
于 2011-11-09T19:39:52.183 に答える
2

このコード

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;
于 2011-11-09T20:23:02.290 に答える
0

cout を test (std::ostream&) に割り当ててもコンパイルしても問題ない理由がわかりません

それは割り当てではないためです。初期化です。

于 2011-11-09T20:13:03.037 に答える
0

C++ では、参照変数は宣言時に初期化する必要があります。

有効:

int x;
int& foo = x;

無効:

int x;
int& foo;
foo = x;
于 2011-11-09T19:42:23.213 に答える
0

参照は再バインドを許可せず、コピーできないため、ポインターを使用する必要がありますstd::ostream

于 2011-11-09T19:44:41.170 に答える