Шрифт:
Ellipse(Point p, int w, int h);
void draw_lines const;
Point center const;
Point focus1 const;
Point focus2 const;
void set_major(int ww) { w=ww; }
int major const { return w; }
void set_minor(int hh) { h=hh; }
int minor const { return h; }
private:
int w;
int h;
};
Класс
Ellipse
можно использовать следующим образом:
Ellipse e1(Point(200,200),50,50);
Ellipse e2(Point(200,200),100,50);
Ellipse e3(Point(200,200),100,150);
Этот фрагмент программы рисует три эллипса с общим центром и разными осями.
< image l:href="#"/>Объект класса
Ellipse
, для которого выполняется условие major==minor
, выглядит как окружность. Эллипс можно также задать с помощью двух фокусов и суммы расстояний от точки до фокусов. Имея объект класса Ellipse
, можем вычислить фокус. Рассмотрим пример.
Point Ellipse::focus1 const
{
return Point(center.x+sqrt(double(w*w–h*h)),center.y);
}
Circle
не является наследником класса Ellipse
? С геометрической точки зрения каждая окружность является эллипсом, но не каждый эллипс является окружностью. В частности, окружность — это эллипс, у которого оба фокуса совпадают. Представьте себе, что мы определили класс Circle
как разновидность класса Ellipse
. В этом случае нам пришлось включать в представление дополнительные величины (окружность определяется центром и радиусом; для определения эллипса необходимы центр и пара осей). Мы не приветствуем излишние затраты памяти там, где они не нужны, но основная причина, по которой класс Circle
не сделан наследником класса Ellipse
, заключается в том, что мы не можем определить его, не заблокировав каким-то образом функции set_major
и set_minor
. Кроме того, фигура не была бы окружностью (что легко распознают математики), если бы мы использовали функцию set_major
, чтобы обеспечить выполнение условия major!=minor
, — по крайней мере, после этого фигура перестанет быть окружностью. Нам не нужен объект, который иногда относится к одному типу (когда major!=minor
), а иногда к другому (когда major==minor
). Нам нужен объект (класса Ellipse
), который иногда выглядит как окружность. С другой стороны, объект класса Circle
никогда не превратится в эллипс с двумя неравными осями.
13.14. Класс Marked_polyline
Часто возникает необходимость пометить точки графика. График можно изобразить в виде ломаной, поэтому нам нужна ломаная, точки которой имели бы метки. Для этого предназначен класс
Marked_polyline
. Рассмотрим пример.
Marked_polyline mpl("1234");
mpl.add(Point(100,100));
mpl.add(Point(150,200));
mpl.add(Point(250,250));
mpl.add(Point(300,200));
В результате выполнения этого фрагмента программы получим следующий результат:
Определение класса
Marked_polyline
имеет следующий вид:
struct Marked_polyline:Open_polyline {
Marked_polyline(const string& m):mark(m)
{
if (m=="") mark = "*";
}
void draw_lines const;
private:
string mark;
};
Поскольку этот класс является наследником класса
Open_polyline
, можем свободно обрабатывать объекты класса Point
, и все что нам для этого необходимо — иметь возможность ставить метки. В частности, функция draw_lines
примет следующий вид:
void Marked_polyline::draw_lines const