Как проверить, является ли ссылка NULL? - PullRequest
1 голос
/ 07 ноября 2011

Я хочу проверить, является ли что-то нулевым, например ::

string xxx(const NotMyClass& obj) {
  if (obj == NULL) {
     //...
  }
}

Но компилятор жалуется на это: есть 5 возможных перегрузок ==.

Итак, я попробовал это:

  if (obj == static_cast<NotMyClass>(NULL)) {

Это происходит сбой, потому что перегрузка NotMyClass == не обрабатывает нули.

edit: для всех, скажите мне, что это не может быть NULL, я определенно получаю что-то NULL как в моем отладчике:

enter image description here

Ответы [ 5 ]

7 голосов
/ 07 ноября 2011

В правильно сформированной программе на C ++ ссылки никогда не бывают NULL (точнее, адрес объекта, на который у вас есть ссылка, никогда не может быть NULL).

Так что не только ответ «нет, нет пути», но и следствие «это не имеет смысла».


Ваше утверждение относительно C также не имеет смысла, так как C не имеет ссылок.

А что касается Java, его «ссылки» во многом похожи на указатели C ++, включая этот.

Сравнение такого специфического поведения между различными языками является чем-то вроде глупого поручения.


Если вам нужно это поведение «необязательного объекта», вам нужны указатели:

std::string xxx(const NotMyClass* ptr) {
  if (ptr == NULL)
     throw SomeException();

  const NotMyClass& ref = *ptr;
  /* ... */
}

Но подумайте, действительно ли вам это нужно; достойной альтернативой может быть boost::optional, если вы действительно это делаете.

5 голосов
/ 07 ноября 2011

То, что вы спрашиваете, не имеет смысла.Ссылки в C ++ никогда не могут быть «нулевыми», поскольку они могут быть созданы только путем наложения псевдонимов на существующий объект, и их нельзя восстановить.Однажды ссылка на x, всегда ссылка на x.

(Ссылка может стать «висячей», если время жизни исходного объекта заканчивается раньше, чем у ссылки, но это ошибка программирования, а непроверяемое условие выполнения.)

4 голосов
/ 07 ноября 2011

Вам не нужно проверять это, так как ссылки в C ++ не могут быть NULL. Указатели могут быть NULL, но вы их здесь не используете.

2 голосов
/ 07 ноября 2011

Как говорили другие, в четко определенном коде никогда нет ссылок на NULL, поэтому вы не обязаны их тестировать.

Это не означает, что они никогда не создаются на практике (но, надеюсь,в промежуточном, а не производственном коде).В некоторых компиляторах возможно, хотя это определенно не стандарт C ++, получить ссылку, адрес которой равен NULL:

int * p = NULL;
int & x = *p;

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

Если вы пытаетесь отладить такую ​​ситуацию, вы можете проверить, не равен ли адрес x NULL:

#include <cassert>
// ...
assert(&x != NULL);
1 голос
/ 07 ноября 2011

Поскольку люди говорили, что ссылки в C ++ никогда не должны быть нулевыми (NULL или nullptr), однако все еще возможно получить нулевые ссылки, особенно если вы выполняете какое-то злое приведение.(Давным-давно я делал это, когда ничего не знал лучше.)

Чтобы проверить, является ли ссылка нулевой (NULL или nullptr), преобразовать ее в указатель и затем протестировать.Итак:

if (&obj == nullptr)

- это то, что вы действительно ищете.

Но теперь, когда вы знаете, как это сделать, не .Просто предположите, что ссылки никогда не могут быть нулевыми, и позвольте приложению аварийно завершить работу, если оно есть, потому что к тому времени что-то еще должно быть ужасно неправильно, и программа должна быть остановлена.

...