Инициализация ссылки на член NULL в C ++ - PullRequest
20 голосов
/ 29 января 2012

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

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

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

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

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

Ответы [ 5 ]

28 голосов
/ 29 января 2012

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

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

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

[1] Из стандарта C ++ 11 :

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

10 голосов
/ 29 января 2012

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

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

7 голосов
/ 29 января 2012

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

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

Object const* const readOnly;
BigClass(): readOnly(0) {}
2 голосов
/ 29 января 2012

Использовать указатель: - const Object * pReadOnly;

0 голосов
/ 26 октября 2012

Это полезно при написании юнит-тестов.Это только место, где это должно быть сделано, но там это очень полезно.

 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&));
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...