Я новичок в C ++, поэтому, когда учусь, я стараюсь использовать множество Java-измов. В любом случае, в Java, если бы у меня был класс с методом поиска, который возвращал бы объект T
из a, Collection< T >
который соответствует определенному параметру, я бы вернул этот объект, а если бы объект не был найден в коллекции, я бы вернулся null
. Тогда в своей вызывающей функции я бы просто проверилif(tResult != null) { ... }
В C ++ я обнаружил, что не могу вернуть null
значение, если объект не существует. Я просто хочу вернуть «индикатор» типа T, который уведомляет вызывающую функцию о том, что объект не найден. Я не хочу создавать исключение, потому что это не исключительные обстоятельства.
Вот как сейчас выглядит мой код:
class Node {
Attr& getAttribute(const string& attribute_name) const {
//search collection
//if found at i
return attributes[i];
//if not found
return NULL; // what should this be?
}
private:
vector<Attr> attributes;
}
Как я могу его изменить, чтобы поставить такой маркер?
источник
std::find(first, last, value)
возвращается,last
если ни один элемент не соответствует.Ответы:
В C ++ ссылки не могут быть нулевыми. Если вы хотите при желании вернуть null, если ничего не найдено, вам нужно вернуть указатель, а не ссылку:
В противном случае, если вы настаиваете на возврате по ссылке, вам следует выбросить исключение, если атрибут не найден.
(Между прочим, меня немного беспокоит, что ваш метод
const
возвращает неconst
атрибут. По философским причинам я предлагаю вернутьсяconst Attr *
. Если вы также можете изменить этот атрибут, вы можете перегрузить его не-const
методом также возвращает неconst
атрибут.)источник
nullptr
вместоNULL
С ++ 11?Здесь есть несколько возможных ответов. Вы хотите вернуть то, что может существовать. Вот несколько вариантов, от наименее предпочтительных до наиболее предпочтительных:
Возврат по ссылке и сигнал о невозможности найти по исключению.
Вероятно, что отсутствие атрибутов - нормальная часть выполнения и, следовательно, не очень исключительная. Обработка этого была бы шумной. Нулевое значение не может быть возвращено, поскольку наличие нулевых ссылок является неопределенным поведением.
Возврат по указателю
Легко забыть проверить, будет ли результат от getAttribute указателем, отличным от NULL, и это простой источник ошибок.
Используйте Boost.Optional
Boost :: optional точно указывает, что здесь происходит, и имеет простые методы проверки того, был ли найден такой атрибут.
Боковое примечание: std :: optional недавно был включен в C ++ 17, так что в ближайшем будущем это будет «стандарт».
источник
boost::optional
не требует больших накладных расходов (без динамического распределения), поэтому он так хорош. Использование его с полиморфными значениями требует обертывания ссылок или указателей.Вы можете легко создать статический объект, представляющий возврат NULL.
И где-то в исходном файле:
источник
Если вам нужно
NULL
возвращаемое значение, вам нужно использовать указатели вместо ссылок.Ссылки сами по себе быть не могут
NULL
.(Примечание для будущих плакатов с комментариями: да, вы можете иметь адрес ссылки NULL, если вы действительно пытаетесь это сделать).
Смотрите мой ответ здесь, чтобы узнать о различиях между ссылками и указателями .
источник
Как вы уже поняли, вы не можете сделать это так, как делали это на Java (или C #). Вот еще одно предложение: вы можете передать ссылку на объект в качестве аргумента и вернуть значение типа bool. Если результат найден в вашей коллекции, вы можете присвоить его передаваемой ссылке и вернуть «истина», иначе вернуть «ложь». Пожалуйста, обратите внимание на этот код.
Вышеупомянутая функция должна найти Оператор по ключу 'token', если она найдет тот, который возвращает true, и присвоить значение параметру Operator & op.
Код вызывающего абонента для этой процедуры выглядит так
источник
Причина, по которой вы не можете вернуть здесь NULL, заключается в том, что вы объявили свой возвращаемый тип как
Attr&
. Завершение&
делает возвращаемое значение «ссылкой», которая, по сути, представляет собой гарантированно ненулевой указатель на существующий объект. Если вы хотите иметь возможность возвращать значение null, измените значениеAttr&
наAttr*
.источник
Вы не можете вернуться,
NULL
потому что возвращаемый тип функции - это объект,reference
а неpointer
.источник
Вы можете попробовать это:
источник