Инициализация ссылки на член в NULL в С++

Можно ли инициализировать ссылочный элемент NULL в С++?
Я пытаюсь сделать что-то вроде этого:

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

Я знаю, что могу это сделать, если инициализировать "ReadOnly" до реальной ссылки на объект, но когда я хочу добавить туда "NULL", я получаю сообщение об ошибке:

"не может преобразовать из 'int' в 'const Object &'

Как я могу это решить?

Ответы

Ответ 1

Нет, ссылки не могут быть NULL в С++. 1

Возможные решения включают:

  • используя указатель вместо ссылки.
  • с фиктивным Object экземпляром, который может использоваться для указания "нет объекта".

[1] Из С++ 11:

[dcl.ref] [...] нулевая ссылка не может существовать в четко определенной программе, потому что единственный способ создать такую ​​ссылку - связать ее с "объект", полученный путем разыменования нулевого указателя, что вызывает поведение undefined.

Ответ 2

Вы не можете "решить" это. Используйте указатель, если хотите, чтобы этот член не указывал на что-либо.

Ссылки должны быть инициализированы для реального объекта, они не могут "указать нигде".

Ответ 3

Это можно сделать, но это почти наверняка крайне плохая идея. Способ сделать это - разыменовать подходящий типизированный указатель NULL, который уже показывает, что это плохая идея: вы приходите к поведению undefined в этот момент, который, однако, обычно имеет тенденцию "работать".

В ссылках на С++ всегда ссылаются на фактический объект. Это отличается от других языков программирования, где "ссылки" на самом деле эквивалентны указателям на С++ (обычно без таких вещей, как арифметика указателей). То, что вы, вероятно, действительно хотите (вы, к сожалению, не сказали, что вы пытаетесь достичь, но задавали вопрос о решении проблемы, которая, вероятно, является частью ошибочного подхода) заключается в том, чтобы вместо этого использовать указатель:

Object const* const readOnly;
BigClass(): readOnly(0) {}

Ответ 4

Используйте указатель: -  const Объект * pReadOnly;

Ответ 5

Это полезно при написании модульных тестов. Это единственное место, которое нужно сделать, но там это очень полезно.

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