private:
protected:
)? Главный ответ состоит в том, что защита класса от нежелательного изменения позволяет разработчику создавать лучшие классы с меньшими усилиями. Этот же аргумент относится и к инвариантам (см. раздел 9.4.3). Подчеркнем эти преимущества на примере определения классов, производных от класса Shape
. В более ранних вариантах класса Shape
мы использовали следующие переменные:Fl_Color lcolor;
int line_style;
Оказывается, это очень ограничивает наши возможности (стиль линии, задаваемый переменной типа int
Fl_Color
не предусматривает невидимые линии) и приводит к довольно запутанному коду. Если бы эти две переменные были открытыми и использовались в пользовательской программе, то мы могли бы улучшить интерфейсную библиотеку только за счет взлома этого кода (поскольку в нем упоминаются имена lcolor
и line_style
). s.add(p)
s.points.push_back(p)
. 14.2.3. Рисование фигур
Мы описали почти все, кроме ядра класса Shape
void draw() const; // работает с цветом и вызывает функцию
// draw_lines
virtual void draw_lines() const; // рисует линии
Основная задача класса Shape
Shape
все остальные функции и оставить его вообще без данных о нем самом, не нанеся вреда нашей основной концепции (см. раздел 14.4); рисование — это главная задача класса Shape
. Он выполняет ее с помощью библиотеки FLTK и операционной системы, но с точки зрения пользователя он выполнят только две функции.• Функция draw()
draw_lines()
.• Функция draw_lines()
Функция draw()
draw_lines()
, чтобы выполнить реальное рисование на экране, а затем пытается восстановить цвет и фигуру, заданные до ее вызова.void Shape::draw() const
{
Fl_Color oldc = fl_color();
// универсального способа идентифицировать текущий стиль
// не существует
fl_color(lcolor.as_int()); // задаем цвет
fl_line_style(ls.style(),ls.width()); // задаем стиль
draw_lines();
fl_color(oldc); // восстанавливаем цвет (предыдущий)
fl_line_style(0); // восстанавливаем стиль линии (заданный
// по умолчанию)
}
Shape::draw()
draw_lines()
, которые лучше “знают”, как их интерпретировать. В принципе всю обработку цвета и стиля можно было бы перепоручить отдельным функциям draw_lines()
, но для этого пришлось бы повторять много одних и тех же фрагментов кода.Рассмотрим теперь, как организовать работу с функцией draw_lines()
Shape
было бы трудно рисовать все, что необходимо для создания любой разновидности фигуры. Для этого пришлось бы хранить в объекте класса Shape каждый пиксель каждой фигуры. Если мы используем вектор vector
, то вынуждены хранить огромное количество точек. И что еще хуже, экран (т.е. устройство для вывода графических изображений) лучше “знает”, как это делать.