Чтение онлайн

на главную - закладки

Жанры

Программирование. Принципы и практика использования 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
. Это решение имеет важные последствия. Например, мы не можем создать объект, связать его, позволить его уничтожить и ожидать, что программа продолжит работать.

void f(Simple_window& w)

{

Rectangle r(Point(100,200),50,30);

w.attach(r);

} // Ой, объекта r больше нет

int main

{

Simple_window win(Point(100,100),600,400,"Мое окно");

// ...

f(win); // возникают проблемы

// ...

win.wait_for_button;

}

Пока мы выходили из функции
f
и входили в функцию
wait_for_button
, объект
r
для объекта win перестал существовать и соответственно выводиться на экран. В главе 17 мы покажем, как создать объект в функции и сохранить его между ее вызовами, а пока должны избежать связывания с объектом, который исчез до вызова функции
wait_for_button
. Для этого можно использовать класс
Vector_ref
, который рассматривается в разделах 14.10 и Г.4.

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

Боги, пиво и дурак. Том 3

Горина Юлия Николаевна
3. Боги, пиво и дурак
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Боги, пиво и дурак. Том 3

Мымра!

Фад Диана
1. Мымрики
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Мымра!

Белые погоны

Лисина Александра
3. Гибрид
Фантастика:
фэнтези
попаданцы
технофэнтези
аниме
5.00
рейтинг книги
Белые погоны

Любовь Носорога

Зайцева Мария
Любовные романы:
современные любовные романы
9.11
рейтинг книги
Любовь Носорога

Я все еще граф. Книга IX

Дрейк Сириус
9. Дорогой барон!
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Я все еще граф. Книга IX

Делегат

Астахов Евгений Евгеньевич
6. Сопряжение
Фантастика:
боевая фантастика
постапокалипсис
рпг
5.00
рейтинг книги
Делегат

Неудержимый. Книга XVI

Боярский Андрей
16. Неудержимый
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Неудержимый. Книга XVI

Чужая дочь

Зика Натаэль
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Чужая дочь

Ночь со зверем

Владимирова Анна
3. Оборотни-медведи
Любовные романы:
любовно-фантастические романы
5.25
рейтинг книги
Ночь со зверем

Месть бывшему. Замуж за босса

Россиус Анна
3. Власть. Страсть. Любовь
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Месть бывшему. Замуж за босса

Совок – 3

Агарев Вадим
3. Совок
Фантастика:
фэнтези
детективная фантастика
попаданцы
7.92
рейтинг книги
Совок – 3

Титан империи 7

Артемов Александр Александрович
7. Титан Империи
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Титан империи 7

Измена. Он все еще любит!

Скай Рин
Любовные романы:
современные любовные романы
6.00
рейтинг книги
Измена. Он все еще любит!

Вечный Данж. Трилогия

Матисов Павел
Фантастика:
фэнтези
юмористическая фантастика
6.77
рейтинг книги
Вечный Данж. Трилогия