web-dev-qa-db-ja.com

C ++でのメンバーへの参照のNULLへの初期化

C++で参照メンバーをNULLに初期化することは可能ですか?
私はこのようなことを試みています:

class BigClass
{
private:
  Object m_inner;
public:
  const Object& ReadOnly;
  BigClass() : ReadOnly(NULL)
  {
    Do stuff.
  }
};

「ReadOnly」をオブジェクトの実際の参照に初期化すればこれを実行できることはわかっていますが、そこに「NULL」を入れたい場合、エラーが発生します。

「 'int'から 'const Object&'に変換できません

どうすればこれを解決できますか?

20
Idov

いいえ、C++では参照をNULLにすることはできません。1

可能な解決策は次のとおりです。

  • 参照の代わりにポインタを使用します。
  • 「オブジェクトがない」ことを示すために使用できるダミーのObjectインスタンスがあります。

[1] C++ 11標準 から:

[dcl.ref][...] null参照は明確に定義されたプログラムには存在できません。そのような参照を作成する唯一の方法は、ヌルポインターを逆参照することによって取得される「オブジェクト」にバインドすることで、未定義の動作が発生します。

28

これを「解決」することはできません。そのメンバーが何もポイントしないようにしたい場合は、ポインターを使用します。

参照は実際のオブジェクトに初期化する必要があり、「どこにもポイントしない」ことはできません。

10
Mat

できますが、ほぼ間違いなく非常に悪い考えです。これを行う方法は、適切な型のNULLポインターを逆参照することです。これは、それが悪い考えであることをすでに示しています。この時点で未定義の動作に到達しますが、通常は「動作」する傾向があります。

C++での参照は、常に実際のオブジェクトを参照するためのものです。これは、「参照」が実際にはC++のpointersと同等である他のプログラミング言語とは異なります(通常、ポインター演算などはありません)。おそらく実際に必要なのは(残念ながら、達成しようとしていることは言わなかったが、おそらく誤ったアプローチの一部である問題の解決策について尋ねられた)代わりにポインタを使用することです。

Object const* const readOnly;
BigClass(): readOnly(0) {}
7
Dietmar Kühl

ポインタを使用します:-const Object * pReadOnly;

2
QuentinUK

単体テストの作成に役立ちます。これは、onlyの場所ですが、実行する必要がありますが、非常に役立ちます。

 Bar& bar(*static_cast<Bar*>(0));
 MockClass mock; // derives from RealClass
 mock.foo(bar);

ここでは、MockClass自体ではなくMockClassを使用するコードをテストしています。

それは万能薬ではありませんが、助けることができます。また、「具体的な」クラスをあざける場合、 GoogleMock はあなたの友達かもしれません。

struct Bar;
struct RealClass {
  int& x_;
  double& y_;
  RealClass(int& x, double& y) :x_(x), y_(y) {}
  virtual void foo(Bar&);
};
struct MockClass: public RealClass {
  MockClass(): RealClass(*(int*)0, *(double*)0) {}
  MOCK_METHOD1(foo, void(Bar&));
};
0
cdunn2001