Читаем Программирование полностью

Как указано в главе 13, мы решили предотвратить прямой доступ к большинству данных-членов класса. Это дает нам возможность проверять “глупые” значения, например отрицательные радиусы у объектов класса Circle. Для простоты реализации мы не проводим полную проверку, поэтому будьте осторожны, работая с числами. Мы отказались от полной и последовательной проверки, желая уменьшить объем кода и понимая, что если пользователь введет “глупое” значение, то ранее введенные данные от этого не пострадают, просто на экране появится искаженное изображение.

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

14.2. Класс Shape

Класс Shape отражает общее понятие о том, что может изображаться в объекте класса Window на экране.

• Понятие, которое связывает графические объекты с нашей абстракцией Window, которая в свою очередь обеспечивает связь с операционной системой и физическим экраном.

• Класс, работающий с цветом и стилем, используемыми при рисовании линий. Для этого он хранит члены классов Line_style и Color (для линий и заполнения).

• Может хранить последовательности объектов класса Point и информацию о том, как их рисовать.


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

Сначала опишем полный класс, а затем подробно его обсудим.

class Shape { // работает с цветом и стилем, хранит последователь -

              // ность точек

public:

  void draw() const; // работает с цветом и рисует линии

  virtual void move(int dx, int dy); // перемещает фигуры +=dx

                                     // и +=dy

  void set_color(Color col);

  Color color() const;


  void set_style(Line_style sty);

  Line_style style() const;


  void set_fill_color(Color col);

  Color fill_color() const;


  Point point(int i) const; // доступ к точкам только для чтения

  int number_of_points() const;


  virtual ~Shape() { }

protected:

  Shape();

  virtual void draw_lines() const; // рисует линии

  void add(Point p);               // добавляет объект p к точкам

  void set_point(int i, Point p);  // points[i]=p;

private:

  vector points;  // не используется всеми фигурами

  Color lcolor;          // цвет для линий и символов

  Line_style ls;

  Color fcolor;          // заполняет цветом

  Shape(const Shape&);   // копирующий конструктор

  Shape& operator=(const Shape&);

};


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

14.2.1. Абстрактный класс

Сначала рассмотрим конструктор класса Shape:


protected:

Shape();


который находится в разделе protected. Это значит, что его можно непосредственно использовать только в классах, производных от класса Shape (используя обозначение :Shape). Иначе говоря, класс Shape можно использовать только в качестве базы для других классов, таких как Line и Open_polyline. Цель ключевого слова protected: — гарантировать, что мы не сможем создать объекты класса Shape непосредственно.

Рассмотрим пример.


Shape ss; // ошибка: невозможно создать объект класса Shape


Перейти на страницу:
Нет соединения с сервером, попробуйте зайти чуть позже