Вход/Регистрация
Программирование. Принципы и практика использования C++ Исправленное издание
вернуться

Страуструп Бьерн

Шрифт:

Проверка аргументов в функции выглядит настолько простой, что становится непонятным, почему люди не проводят ее постоянно? Одна из причин — пренебрежение ошибками, вторая — неряшливость при написании программ, но существуют и более уважительные причины.

• Мы не можем модифицировать определение функции. Функция является частью библиотеки, поэтому ее невозможно изменить. Возможно, она будет использована другими людьми, не разделяющими вашего подхода к обработке ошибок. Возможно, она принадлежит кому-то еще, и вы не имеете доступ к ее исходному коду. Возможно, она включена в постоянно обновляющуюся библиотеку, так что если вы измените эту функцию, то будете вынуждены изменять ее в каждой новой версии.

• Вызываемая функция не знает, что делать при выявлении ошибки. Эта ситуация типична для библиотечных функций. Автор библиотеки может выявить ошибку, но только вы знаете, что в таком случае следует делать.

• Вызываемая функция не знает, откуда ее вызвали. Получив сообщение об ошибке, вы понимаете, что произошло нечто непредвиденное, но не можете знать, как именно выполняемая программа оказалась в данной точке. Иногда необходимо, чтобы сообщение было более конкретным.

• Производительность. Для небольшой функции стоимость проверки может перевесить стоимость вычисления самого результата. Например, в случае с функцией

area
проверка вдвое увеличивает ее размер (т.е. удваивает количество машинных инструкций, которые необходимо выполнить, а не просто длину исходного кода). В некоторых программах этот факт может оказаться критически важным, особенно если одна и та же информация проверяется постоянно, когда функции вызывают друг друга, передавая информацию более или менее без искажений.

Итак, что делать? Проверять аргументы в функции, если у вас нет веских причин поступать иначе.

После обсуждения некоторых тем, связанных с этим вопросом, мы вернемся к нему в разделе 5.10.

5.5.3. Сообщения об ошибках

Рассмотрим немного иной вопрос: что делать, если вы проверили набор аргументов и обнаружили ошибку? Иногда можно вернуть сообщение “Неправильное значение”. Рассмотрим пример.

// Попросим пользователя ввести да или нет;

// Символ 'b' означает неверный ответ (т.е. ни да ни нет)

char ask_user(string question)

{

cout << question << "? (да или нет)\n";

string answer = " ";

cin >> answer;

if (answer =="y" || answer=="yes") return 'y';

if (answer =="n" || answer=="no") return 'n';

return 'b'; // 'b', если "ответ неверный"

}

// Вычисляет площадь прямоугольника;

// возвращает –1, если аргумент неправильный

int area(int length, int width)

{

if (length<=0 || width <=0) return –1;

return length*width;

}

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

• Теперь проверку должны осуществлять и вызываемая функция, и все вызывающие функции. Вызывающая функция должна провести лишь самую простую проверку, но остается вопрос, как написать этот код и что делать, если обнаружится ошибка.

• Программист может забыть проверить аргументы в вызывающей функции, что приведет к непредсказуемым последствиям.

• Многие функции не имеют возможность возвращать дополнительные значения, чтобы сообщить об ошибке. Например, функция, считывающая целое число из потока ввода (скажем, оператор

>>
потока
cin
), может возвращать любое целое число, поэтому использовать целое число в качестве индикатора ошибки бессмысленно.

Вторая ситуация, в которой проверка в вызывающем модуле не выполняется, может легко привести к неожиданностям

Рассмотрим пример.

int f(int x, int y, int z)

{

int area1 = area(x,y);

if (area1<=0) error("Неположительная площадь");

int area2 = framed_area(1,z);

int area3 = framed_area(y,z);

double ratio = double(area1)/area3;

  • Читать дальше
  • 1
  • ...
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: