Программирование. Принципы и практика использования C++ Исправленное издание
Шрифт:
Взгляните на этот код! Вы уверены, что он правильный? Он вам нравится? Легко ли его читать? Действительно,
Существует более правильное решение!
Посмотрите на исходный код.
Он может быть неверным, но, по крайней мере, мы можем понять, что должно происходить. Мы можем сохранить эту ясность, поместив проверку ошибки в функцию
5.5.2. Обработка ошибок в вызываемом модуле
Проверка корректности аргументов в функцию
Это решение выглядит неплохо, и нам больше нет необходимости писать проверку для каждого вызова функции
Отметим нечто интересное: мы почти бессознательно заменили подход “вызывающий модуль должен сам проверять аргументы” на подход “функция должна проверять свои собственные аргументы”. Одним из преимуществ второго подхода является то, что проверка аргументов осуществляется в единственном месте. Теперь необязательно просматривать вызовы функции по всей программе. Более того, проверка производится именно там, где эти аргументы используются, поэтому мы имеем всю информацию, необходимую для проверки.
Итак, применим найденное решение к функции
Этот фрагмент будет перехватывать все ошибки, возникающие в модулях, вызывающих функцию
Проверка аргументов в функции выглядит настолько простой, что становится непонятным, почему люди не проводят ее постоянно? Одна из причин — пренебрежение ошибками, вторая — неряшливость при написании программ, но существуют и более уважительные причины.
• Мы не можем модифицировать определение функции. Функция является частью библиотеки, поэтому ее невозможно изменить. Возможно, она будет использована другими людьми, не разделяющими вашего подхода к обработке ошибок. Возможно, она принадлежит кому-то еще, и вы не имеете доступ к ее исходному коду. Возможно, она включена в постоянно обновляющуюся библиотеку, так что если вы измените эту функцию, то будете вынуждены изменять ее в каждой новой версии.
• Вызываемая функция не знает, что делать при выявлении ошибки. Эта ситуация типична для библиотечных функций. Автор библиотеки может выявить ошибку, но только вы знаете, что в таком случае следует делать.
• Вызываемая функция не знает, откуда ее вызвали. Получив сообщение об ошибке, вы понимаете, что произошло нечто непредвиденное, но не можете знать, как именно выполняемая программа оказалась в данной точке. Иногда необходимо, чтобы сообщение было более конкретным.
• Производительность. Для небольшой функции стоимость проверки может перевесить стоимость вычисления самого результата. Например, в случае с функцией
После обсуждения некоторых тем, связанных с этим вопросом, мы вернемся к нему в разделе 5.10.
5.5.3. Сообщения об ошибках
Рассмотрим немного иной вопрос: что делать, если вы проверили набор аргументов и обнаружили ошибку? Иногда можно вернуть сообщение “Неправильное значение”. Рассмотрим пример.