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

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

Шрифт:

Мы должны знать, что функция

framed_area
вычитает
2
из каждого аргумента. Но мы не должны знать такие детали! А что, если кто-нибудь изменит функцию
framed_area
и вместо
2
станет вычитать
1
?

В этом случае нам пришлось бы проверить каждый вызов функции

framed_area
и соответствующим образом изменить фрагменты кода, обрабатывающего ошибки. Такой код называется “хрупким”, потому что легко выходит из строя. Он также иллюстрирует вред от “магических констант” (см. раздел 4.3.1). Код можно сделать более надежным, дав величине, вычитаемой функцией
framed_area
, имя.

const int frame_width = 2;

int framed_area(int x, int y) // вычисляем площадь,

// ограниченную рамкой

{

return area(x–frame_width,y–frame_width);

}

Это имя можно использовать в коде, вызывающем функцию

framed_area
.

if (1–frame_width<=0 || z–frame_width<=0)

error("неположительный второй аргумент функции area \\

при вызове из функции framed_area");

int area2 = framed_area(1,z);

if (y–frame_width<=0 || z–frame_width<=0)

error("неположительный аргумент функции area \\

при вызове из функции framed_area");

int area3 = framed_area(y,z);

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

framed_area
всплыли наружу.

Существует более правильное решение!

Посмотрите на исходный код.

int area2 = framed_area(1,z);

int area3 = framed_area(y,z);

Он может быть неверным, но, по крайней мере, мы можем понять, что должно происходить. Мы можем сохранить эту ясность, поместив проверку ошибки в функцию

framed_area
.

5.5.2. Обработка ошибок в вызываемом модуле

Проверка корректности аргументов в функцию

framed_area
не вызывает затруднений, а выдачу сообщения об ошибках можно по-прежнему поручить функции
error
.

int framed_area(int x, int y) // вычисляем площадь, ограниченную рамкой

{

const int frame_width = 2;

if (x–frame_width<=0 || y–frame_width<=0)

error("неположительный аргумент функции area \\

при вызове из функции framed_area");

return area(x–frame_width,y–frame_width);

}

Это решение выглядит неплохо, и нам больше нет необходимости писать проверку для каждого вызова функции

framed_area
. Для полезной функции, которая 500 раз вызывается в крупной программе, это большое преимущество. Более того, если обработка ошибок по какой-то причине изменится, нам будет достаточно изменить код только в одном месте.

Отметим нечто интересное: мы почти бессознательно заменили подход “вызывающий модуль должен сам проверять аргументы” на подход “функция должна проверять свои собственные аргументы”. Одним из преимуществ второго подхода является то, что проверка аргументов осуществляется в единственном месте. Теперь необязательно просматривать вызовы функции по всей программе. Более того, проверка производится именно там, где эти аргументы используются, поэтому мы имеем всю информацию, необходимую для проверки.

Итак, применим найденное решение к функции

area
.

int area(int length, int width) // вычисляем площадь прямоугольника

{

if (length<=0 || width <=0)

error("неположительный аргумент area");

return length*width;

}

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

area
, поэтому их теперь необязательно проверять в функции
framed_area
. Однако вы можете требовать большего — чтобы сообщение об ошибке было более конкретным.

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

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

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

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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