В данном приложении документируются базовые классы, которые применялись в примерах кода на C++ в описаниях различных паттернов проектирования. Мы специально стремились сделать эти классы простыми и минимальными. Будут описаны следующие классы:
• List – упорядоченный список объектов;
• Iterator – интерфейс для последовательного доступа к объектам в агрегате;
• ListIterator – итератор для обхода списка;
• Point – точка с двумя координатами;
• Rect – прямоугольник, стороны которого параллельны осям координат.
Некоторые появившиеся сравнительно недавно стандартные типы C++, возможно, реализованы еще не во всех компиляторах. В частности, если ваш компилятор не поддерживает тип bool, его можно определить самостоятельно:
typedef int bool;
const int true = 1;
const int false = 0;
Шаблон класса List представляет собой базовый контейнер для хранения упорядоченного списка объектов. В списке хранятся значения элементов, то есть он пригоден как для встроенных типов, так и для экземпляров классов. Например, запись List<int> объявляет список целых int. Но в большинстве паттернов
в списке хранятся указатели на объекты, скажем, List<Glyph*>. Это позволяет использовать класс List для хранения разнородных объектов (точнее, указателей на них).
Для удобства в классе List есть синонимы для операций со стеком. Это позволяет явно использовать список в роли стека, не определяя дополнительного класса:
template <class Item>
class List {
public:
List(long size = DEFAULT_LIST_CAPACITY);
List(List&);
~List();
List& operator=(const List&);
long Count() const;
Item& Get(long index) const;
Item& First() const;
Item& Last() const;
bool Includes(const Item&) const;
void Append(const Item&);
void Prepend(const Item&);
void Remove(const Item&);
void RemoveLast();
void RemoveFirst();
void RemoveAll();
Item& Top() const;
void Push(const Item&);
Item& Pop();
};
В следующих разделах операции описываются более подробно.
List(long size) – инициализирует список. Параметр size определяет начальное число элементов в списке.
List(List&) – замещает определяемый по умолчанию копирующий конструктор для правильной инициализации данных-членов.
~List() – освобождает внутренние структуры данных списка, но не элементы списка. Не предполагается, что у этого класса будут производные, поэтому деструктор не объявлен виртуальным.
List& operator=(const List&) – реализует операцию присваивания.
Следующие операции обеспечивают доступ к элементам списка.
long Count() const – возвращает число объектов в списке.
Item& Get(long index) const – возвращение объекта с заданным индексом.
Item& First() const – возвращает первый объект в списке.
Item& Last() const – возвращение последнего объекта в списке.
void Append(const Item&) – добавляет свой аргумент в конец списка.
void Prepend(const Item&) – добавляет свой аргумент в начало списка.
void Remove(const Item&) – удаляет заданный элемент из списка. Для применения этой операции требуется, чтобы тип элементов поддерживал оператор сравнения на равенство ==.
void RemoveFirst() – удаляет первый элемент из списка.
void RemoveLast() – удаление последнего элемента из списка.
void RemoveAll() – удаляет все элементы из списка.
Item& Top() const – возвращает элемент, находящийся на вершине стека.
void Push(const Item&) – «заталкивает» элемент в стек.
Item& Pop() – «выталкивает» элемент с вершины стека.
Iterator – это абстрактный класс, который определяет интерфейс обхода агрегата:
template <class Item>
class Iterator {
public:
virtual void First() = 0;
virtual void Next() = 0;
virtual bool IsDone() const = 0;
virtual Item CurrentItem() const = 0;
protected:
Iterator();
};
Операции делают следующее:
virtual void First() – позиционирует итератор на первый объект в агрегате.
virtual void Next() – позиционирует итератор на следующий по порядку объект.
virtual bool IsDone() const – возвращает true, если больше не осталось объектов.
virtual Item CurrentItem() const – возвращает объект, находящийся в текущей позиции.
ListIterator реализует интерфейс класса Iterator для обхода списка List. Его конструктор принимает в качестве аргумента список, который нужно обойти:
template <class Item>
class ListIterator : public Iterator<Item> {
public:
ListIterator(const List<Item>* aList);
virtual void First();
virtual void Next();
virtual bool IsDone() const;
virtual Item CurrentItem() const;
};
Класс Point представляет точку на плоскости с помощью декартовых координат, поддерживает минимальный набор арифметических операций над векторами. Координаты точки определяются так:
typedef float Coord;
Операции класса Point не нуждаются в пояснениях:
class Point {
public:
static const Point Zero;
Point(Coord x = 0.0, Coord y = 0.0);
Coord X() const; void X(Coord x);
Coord Y() const; void Y(Coord y);
friend Point operator+(const Point&, const Point&);
friend Point operator-(const Point&, const Point&);
friend Point operator*(const Point&, const Point&);
friend Point operator/(const Point&, const Point&);
Point& operator+=(const Point&);
Point& operator-=(const Point&);
Point& operator*=(const Point&);
Point& operator/=(const Point&);
Point operator-();
friend bool operator==(const Point&, const Point&);
friend bool operator!=(const Point&, const Point&);
friend ostream& operator<<(ostream&, const Point&);
friend istream& operator>>(istream&, Point&);
};
Статический член Zero представляет начало координат Point(0, 0).
Класс Rect представляет прямоугольник, стороны которого параллельны осям координат. Прямоугольник определяется начальной вершиной и размерами, то есть шириной и высотой. Операции класса Rect не нуждаются в пояснениях:
class Rect {
public:
static const Rect Zero;
Rect(Coord x, Coord y, Coord w, Coord h);
Rect(const Point& origin, const Point& extent);
Coord Width() const; void Width(Coord);
Coord Height() const; void Height(Coord);
Coord Left() const; void Left(Coord);
Coord Bottom() const; void Bottom(Coord);
Point& Origin() const; void Origin(const Point&);
Point& Extent() const; void Extent(const Point&);
void MoveTo(const Point&);
void MoveBy(const Point&);
bool IsEmpty() const;
bool Contains(const Point&) const;
};
Статический член Zero представляет вырожденный прямоугольник:
Rect(Point(0, 0), Point(0, 0));