Программирование. Принципы и практика использования C++ Исправленное издание, стр. 175

• Продемонстрировать связь между кодом и создаваемыми рисунками.

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

• Научить вас размышлять о проектировании программ, в частности о том, как выразить понятия в виде классов. Почему эти классы устроены так, а не иначе? Как еще их можно было бы написать? Вы можете принять много-много проектных решений, и в большинстве своем они будут отличаться от наших незначительно, а в некоторых случаях — кардинально.

Итак, пожалуйста, не торопитесь, иначе пропустите нечто важное и не сможете выполнить упражнения. 

13.2. Классы Point и Line

 Самой главной частью любой графической системы является точка. Определив это понятие, вы определите все ваше геометрическое пространство. В данной книге мы используем обычное, компьютерно-ориентированное двумерное представление точек в виде пары целочисленных координат (x, y). Как указано в разделе 12.5, координаты x изменяются от нуля (левого края экрана) до

x_max()
(правого края экрана); координаты y изменяются от нуля (верхнего края экрана) до
y_max()
(нижнего края экрана).

Как определено в файле

Point.h
, класс
Point
— это просто пара чисел типа
int
(координаты).

struct Point {

  int x, y;

  Point(int xx, int yy):x(xx), y(yy) { }

  Point() :x(0), y(0) { }

};

bool operator==(Point a, Point b) { return a.x==b.x && a.y==b.y; }

bool operator!=(Point a, Point b) { return !(a==b); }

В файле

Graph.h
определены также класс
Shape
, подробно описанный в главе 14, и класс
Line
.

struct Line:Shape {       // класс Line — это класс Shape,

                          // определенный двумя точками

Line(Point p1, Point p2); // создаем объект класса Line

                          // из двух объектов класса Points

};

Класс

Line
— это разновидность класса
Shape
. Именно это означает строка
“:Shape”
. Класс
Shape
называют базовым (base class) по отношению к классу
Line
. В принципе класс
Shape
содержит возможности, чтобы упростить определение класса
Line
. Как только мы столкнемся с конкретными фигурами, например
Line
или
Open_polyline
, то увидим, что это значит (см. главу 14).

Класс

Line
определяется двумя объектами класса
Point
. Оставляя в стороне “леса” (директивы #include и прочие детали, описанные в разделе 12.3), мы можем создать линию и нарисовать ее на экране.

// рисуем две линии

Simple_window win1(Point(100,100),600,400,"Two lines");

Line horizontal(Point(100,100),Point(200,100)); // горизонтальная

                                                // линия

Line vertical(Point(150,50),Point(150,150));    // вертикальная

                                                // линия

win1.attach(horizontal);                        // связываем их

                                                // с экраном

win1.attach(vertical);

win1.wait_for_button();                         // изобразить!

Выполнив этот фрагмент кода, получим на экране следующее изображение.

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

Line vertical(Point(150,50),Point(150,150));

создает (вертикальную) линию, соединяющую точки (150,50) и (150,150). Разумеется, существуют детали реализации, но вам необязательно знать их, чтобы создавать линии. Реализация конструктора класса

Line
довольно проста.

Программирование. Принципы и практика использования C++ Исправленное издание - _124.png

Line::Line(Point p1, Point p2) // создаем линию по двум точкам

{

  add(p1); // добавляем точку p1

  add(p2); // добавляем точку p2

}

Иначе говоря, конструктор просто добавляет две точки. Добавляет куда? И как объект класса

Line
рисуется в окне? Ответ кроется в классе
Shape
. Как будет описано в главе 14, класс
Shape
может хранить точки, определяющие линии, знает, как рисовать линии, определенные парами точек, и имеет функцию
add()
, позволяющую добавлять объекты в объекты класса
Point
. Основной момент здесь заключается в том, что определение класса
Line
тривиально. Большая часть работы по реализации выполняется системой, поэтому программист может сосредоточиться на создании простых классов, которые легко использовать.

С этого момента оставим в стороне определение класса

Simple_window
и вызовы функции
attach()
. Они не более чем “леса”, необходимые для завершения программы, но ничего не добавляющие к специфике объектов класса
Shape

13.3. Класс Lines

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

Lines
.

struct Lines:Shape {            // связанные друг с другом линии