Бьерн Страуструп. Язык программирования С++ Второе дополненное издание



Pdf көрінісі
бет123/256
Дата11.07.2022
өлшемі2,87 Mb.
#37591
1   ...   119   120   121   122   123   124   125   126   ...   256
Байланысты:
Бьерн Страуструп. Язык программирования С . М Бином, 2011

6.4.2 Библиотека фигур 
Начнем с определения общего понятия фигуры. Определение должно быть таким, чтобы им можно 
было воспользоваться (как базовым классом shape) в разных классах, представляющих все конкретные 
фигуры (окружности, квадраты и т.д.). Оно также должно позволять работать со всякой фигурой 
исключительно с помощью интерфейса, определяемого классом shape: 
struct shape { 
static shape* list; 
shape* 
next; 
shape() { next = list; list = this; } 
virtual point north() const = 0; 
virtual point south() const = 0; 
virtual point east() const = 0; 
virtual point west() const = 0; 
virtual point neast() const = 0; 
virtual point seast() const = 0; 
virtual point nwest() const = 0; 
virtual point swest() const = 0; 
virtual void draw() = 0; 
virtual void move(int, int) = 0; 
}; 
Фигуры помещаются на экран функцией draw(), а движутся по нему с помощью move(). Фигуры можно 
помещать относительно друг друга, используя понятие точек контакта. Для обозначения точек контакта 
используются названия сторон света в компасе: north - север, ... , neast - северо-восток, ... , swest - юго-
запад. Класс каждой конкретной фигуры сам определяет смысл этих точек и определяет, как рисовать 
фигуру. Конструктор shape::shape() добавляет фигуру к списку фигур shape::list. Для построения этого 
списка используется член next, входящий в каждый объект shape. Поскольку нет смысла в объектах 
типа общей фигуры, класс shape определен как абстрактный класс. 
Для задания отрезка прямой нужно указать две точки или точку и целое. В последнем случае отрезок 
будет горизонтальным, а целое задает его длину. Знак целого показывает, где должна находиться 
заданная точка относительно конечной точки, т.е. слева или справа от нее: 
class line : public shape { 
/* 
отрезок прямой ["w", "e" ] 
north() определяет точку - `` выше центра отрезка и 
так далеко на север, как самая его северная точка'' 
*/ 
point w, e; 
public: 
point north() const { return point((w.x+e.x)/2,e.ypoint south() const { return point((w.x+e.x)/2,e.ypoint 
east() 
const; 


Бьерн Страуструп.
Язык программирования С++ 
 
161 
point 
west() 
const; 
point 
neast() 
const; 
point 
seast() 
const; 
point 
nwest() 
const; 
point 
swest() 
const; 
void move(int a, int b) 
{ w.x +=a; w.y +=b; e.x +=a; e.y +=b; } 
void draw() { put_line(w,e); } 
line(point a, point b) { w = a; e = b; } 
line(point a, int l) { w = point(a.x+l-1,a.y); e = a; } 
}; 
Аналогично определяется прямоугольник: 
class rectangle : public shape { 
/* nw ------ n ----- ne 
| | 
| | 
w c e 
| | 
| | 
sw ------ s ----- se 
*/ 
point sw, ne; 
public: 
point north() const { return point((sw.x+ne.x)/2,ne.y); } 
point south() const { return point((sw.x+ne.x)/2,sw.y); } 
point 
east() 
const; 
point 
west() 
const; 
point neast() const { return ne; } 
point 
seast() 
const; 
point 
nwest() 
const; 
point swest() const { return sw; } 
void move(int a, int b) 
{ sw.x+=a; sw.y+=b; ne.x+=a; ne.y+=b; } 
void 
draw(); 
rectangle(point,point); 
}; 
Прямоугольник строится по двум точкам. Конструктор усложняется, так как необходимо выяснять 
относительное положение этих точек: 
rectangle::rectangle(point a, point b) 

if (a.x <= b.x) { 
if (a.y <= b.y) { 
sw 

a; 
ne 

b; 

else 

sw 

point(a.x,b.y); 
ne 

point(b.x,a.y); 


else 

if (a.y <= b.y) { 
sw 

point(b.x,a.y); 
ne 

point(a.x,b.y); 

else 

sw 

b; 


Бьерн Страуструп.
Язык программирования С++ 
 
162 
ne 

a; 



Чтобы нарисовать прямоугольник, надо нарисовать четыре отрезка: 
void rectangle::draw() 

point 
nw(sw.x,ne.y); 
point 
se(ne.x,sw.y); 
put_line(nw,ne); 
put_line(ne,se); 
put_line(se,sw); 
put_line(sw,nw); 

В библиотеке фигур есть определения фигур и функции для работы с ними
void shape_refresh(); // нарисовать все фигуры 
void stack(shape* p, const shape* q); // 
поместить p над q 
Функция обновления фигур нужна, чтобы работать с нашим примитивным представлением экрана; она 
просто заново рисует все фигуры. Отметим, что эта функция не имеет понятия, какие фигуры она 
рисует: 
void shape_refresh() 

screen_clear(); 
for (shape* p = shape::list; p; p=p->next) p->draw(); 
screen_refresh(); 

Наконец, есть одна действительно сервисная функция, которая рисует одну фигуру над другой. Для 
этого она определяет юг (south()) одной фигуры как раз над севером (north()) другой: 
void stack(shape* p, const shape* q) // 
поместить p над q 

point n = q->north(); 
point s = p->south(); 
p->move(n.x-s.x,n.y-s.y+1); 

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


Достарыңызбен бөлісу:
1   ...   119   120   121   122   123   124   125   126   ...   256




©emirsaba.org 2024
әкімшілігінің қараңыз

    Басты бет