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

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

Шрифт:

Line ln(Point(100,200),Point(300,400));

Mark m(Point(100,200),'x'); // отображает отдельную точку

// в виде буквы "x"

Circle c(Point(200,200),250);

Все функции, работающие с точками, используют класс

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

void draw_line(Point p1,Point p2); // от p1 до p2 (наш стиль)

void draw_line(int x1,int y1,int x2,int y2); // от (x1,y1)

// до (x2,y2)

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

Point
позволит также избежать путаницы между парами координат и другими парами целых чисел: шириной и высотой. Рассмотрим пример.

draw_rectangle(Point(100,200),300,400); // наш стиль

draw_rectangle (100,200,300,400); // альтернатива

При первом вызове функция рисует прямоугольник по заданной точке, ширине и высоте. Это легко угадать. А что можно сказать о втором вызове? Имеется в виду прямоугольник, определенный точками (100,200) и (300,400)? Или прямоугольник, определенный точкой (100,200), шириной 300 и высотой 400? А может быть, программист имел в виду нечто совершенно другое (хотя и разумное)? Последовательно используя класс

Point
, мы можем избежать таких недоразумений.

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

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

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

Такие коды называют обобщенными (generic); подробно мы рассмотрим их в главах 19–21.

14.1.3. Именование

Логически разные операции имеют разные имена. И опять-таки, несмотря на то, что это очевидно, существуют вопросы: почему мы связываем объект класса

Shape
с объектом класса
Window
, но добавляем объект класса
Line
к объекту класса
Shape
? В обоих случаях мы “помещаем нечто во что-то”, так почему бы не назвать такие операции одинаково? Нет. За этой схожестью кроется фундаментальная разница. Рассмотрим пример.

Open_polyline opl;

opl.add(Point(100,100));

opl.add(Point(150,200));

opl.add(Point(250,250));

Здесь мы копируем три точки в объект

opl
. Фигуре
opl
безразлично, что будет с нашими точками после вызова функции
add
; она хранит свои собственные копии этих точек. На самом деле мы редко храним копии точек, а просто передаем их фигуре. С другой стороны, посмотрим на следующую инструкцию:

win.attach(opl);

Здесь мы создаем связь между окном win и нашей фигурой

opl
; объект
win
не создает копию объекта
opl
, а вместо этого хранит ссылку на него. Итак, мы должны обеспечить корректность объекта
opl
, поскольку объект
win
использует его. Иначе говоря, когда окно
win
использует фигуру
opl
, оно должно находиться в ее области видимости. Мы можем обновить объект
opl
, и в следующий раз объект
win
будет рисовать фигуру
opl
с изменениями. Разницу между функциями
attach
и
add
можно изобразить графически.

Функция

add
использует механизм передачи параметров по значению (копии), а функция
attach
— механизм передачи параметров по ссылке (использует общий объект). Мы могли бы решить копировать графические объекты в объекты класса
Window
. Однако это была бы совсем другая модель программирования, которая определяется выбором функции
add
, а не
attach
. Мы решили просто связать графический объект с объектом класса
Window
. Это решение имеет важные последствия. Например, мы не можем создать объект, связать его, позволить его уничтожить и ожидать, что программа продолжит работать.

  • Читать дальше
  • 1
  • ...
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • ...

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

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

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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