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

ЖАНРЫ

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

Цель нашей интерфейсной библиотеки — компенсировать шок, вызванный сложностью библиотек графики и графического пользовательского интерфейса. Мы опишем только два десятка классов с немногими операциями. Тем не менее они позволяют создавать полезные графические приложения. Кроме того, эти классы позволяют ввести ключевые понятия графики и графического пользовательского интерфейса. С их помощью читатели уже могут представлять результаты своей работы в виде простых графиков. Прочитав эту главу, вы сможете расширить спектр своих приложений и удовлетворить больше требований. Прочитав к тому же главу 14, вы освоите основные идеи и методы проектирования, которые позволят вам глубже разобраться в графических библиотеках и создать еще более сложные приложения. Этого можно достичь либо включив в свои программы описанные здесь

классы, либо адаптировав другие библиотеки графики и графического пользовательского интерфейса.

Основные интерфейсные классы перечислены в следующей таблице.

Классы

Function
и
Axis
описываются в главе 15. В главе 16 рассматриваются основные интерфейсные классы.

Исходный код состоит из следующих файлов.

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

Shape
или
Widget
.

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

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

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

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

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

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
довольно проста.

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

{

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

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

}

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

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

Поделиться с друзьями: