Инициализация ссылки на член в 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&));
};