Язык программирования C++ для профессионалов



         

Абстрактные типы


Самый простой способ ослабить связь между пользователем класса и его создателем, а также между программами, в которых объекты создаются, и программами, в которых они используются, состоит в введении понятия абстрактных базовых классов. Эти классы представляют интерфейс со множеством реализаций одного понятия. Рассмотрим класс set, содержащий множество объектов типа T:

class set { public: virtual void insert(T*) = 0; virtual void remove(T*) = 0;

virtual int is_member(T*) = 0;

virtual T* first() = 0; virtual T* next() = 0;

virtual ~set() { } };

Этот класс определяет интерфейс с произвольным множеством (set), опираясь на встроенное понятие итерации по элементам множества. Здесь типично отсутствие конструктора и наличие виртуального деструктора, см. также §6.7. Рассмотрим пример:

class slist_set : public set, private slist { slink* current_elem; public: void insert(T*); void remove(T*);

int is_member(T*);

virtual T* first(); virtual T* next();

slist_set() : slist(), current_elem(0) { } };

class vector_set : public set, private vector { int current_index; public: void insert(T*); void remove(T*);

int is_member(T*);

T* first() { current_index = 0; return next(); } T* next();

vector_set(int initial_size) : array(initial_size), current_index(0) { } };

Реализация конкретного типа используется как частный базовый класс, а не член класса. Это сделано и для удобства записи, и потому, что некоторые конкретные типы могут иметь защищенный интерфейс с целью предоставить более прямой доступ к своим членам из производных классов. Кроме того, подобным образом в реализации могут использоваться некоторые классы, которые имеют виртуальные функции и не являются конкретными типами. Только с помощью образования производных классов можно в новом классе изящно переопределить (подавить) виртуальную функцию класса реализации. Интерфейс определяется абстрактным классом.

Теперь пользователь может записать свои функции из §13.2 таким образом:

void my(set& s) { for (T* p = s.first(); p; p = s.next()) { // мой код } // ... }




Содержание  Назад  Вперед