В библиотеке у меня есть функция, которая ищет ключ в базе данных и возвращает неконстантную ссылку на объект. Я хочу обработать случай, когда ключ не найден, что обычно вызвано ошибкой при вызове функции. Эта ситуация настолько плоха, что программа не может продолжить работу, поэтому я распечатываю сообщение, чтобы помочь обнаружить ошибку, и вызываю exit(1)
. Проблема с оператором return, который никогда не будет выполнен в этом случае, но все равно должен быть там. Если бы это был указатель, я мог бы просто return nullptr;
, но со ссылкой? Должен ли я сделать что-то вроде этого псевдокода?
Type & get(const Key & k) {
if (my_db.key_exists(k)) {
return my_db.at(k);
}
std::cerr << k << " not found\n";
exit(1);
return *(new Type(some_dummy_parameters));
}
Это выглядит так ужасно! Может мне стоит просто избегать такой функции. Пожалуйста, дайте мне знать ваше мнение!
4 ответа
Эта ситуация настолько плохая, что программа не может продолжить работу, поэтому я распечатываю сообщение, чтобы помочь обнаружить ошибку, и вызываю exit (1).
Нет. Если этот код является частью библиотеки, она не должна решать, следует ли завершать приложение или нет.
Что делать, если файл открыт и его нужно закрыть, или какой-то другой ресурс нужно очистить, или если пользователь вашего класса БД хочет зарегистрировать ошибку и продолжить делать что-то еще?
Ответ - что угодно, но не то, что вы делаете сейчас. Вызывает исключение, возвращает код ошибки и т. Д., Но не закрывает приложение в библиотеке или коде класса.
Вы не поверите, но существовала коммерческая библиотека БД, которая делала именно то, что вы делаете (закрываете приложение). Они получили много гневных откликов от пользователей своей библиотеки о том, почему они неожиданно закрывают приложение. И вы знаете, что - ответ, данный клиентам, заключался в том, что «мы чувствовали, что ошибка была достаточно серьезной, чтобы остановить приложение, потому что наша библиотека не может продолжать работать должным образом». Это не только плохие доводы, это граничит с высокомерием, и покупатели дают им знать об этом.
Исключения
Это обычная ситуация во многих программах. Чтобы преодолеть это, используются исключения.
- Для обработки непредвиденных ситуаций из кода создаются и «выбрасываются» новые исключения.
- Затем они должны быть «пойманы» программой, вызывающей функцию.
Подробнее об исключениях можно узнать здесь.
Надеюсь это поможет.
Ответ, как сказали другие респонденты, должен быть таким: выбросить исключение ...
Type & get(const Key & k) {
if( !my_db.key_exists(k) ) {
std::stringstream error;
error << "key " << k << " not found";
throw std::runtime_error(error);
}
return my_db.at(k);
}
Библиотека никогда не должна выходить из приложения хозяйки.
Используйте «return null», переходите в «несогласованное состояние», при котором при каждом вызове вы возвращаете NULL.
пользователь библиотеки должен будет справиться с этим.
Или исключения ...
Похожие вопросы
Связанные вопросы
Новые вопросы
c++
C++ — это язык программирования общего назначения. Изначально он разрабатывался как расширение C и имел аналогичный синтаксис, но теперь это совершенно другой язык. Используйте этот тег для вопросов о коде, который будет скомпилирован с помощью компилятора C++. Используйте тег версии для вопросов, связанных с конкретной стандартной версией [C++11], [C++14], [C++17], [C++20] или [C++23]. и т.д.
exit
в C++ (поскольку он не вызывает деструкторы каких-либо локальных переменных) и распространять ошибки доmain
, откуда я могу вернуться.!my_db.key_exists(k)
в операторе if.