Язык программирования C++ от Страуструпа


.Абстрактные типы - часть 5


Здесь классы set и iter предоставляют интерфейсы, а slist и stream являются частными классами и представляют реализации. Очевидно, нельзя перевернуть эту иерархию классов и, предоставляя общие интерфейсы, строить производные конкретные типы от абстрактных классов. В такой иерархии каждая полезная операция над каждым полезным абстрактным понятием должна представляться в общем абстрактном базовом классе. Дальнейшее обсуждение этой темы содержится в $$13.6.

Приведем пример простого абстрактного типа, являющегося итератором объектов типа T:

class iter {

  virtual T* first() = 0;

  virtual T* next() = 0;

  virtual ~iter() { }

};

 

class slist_iter : public iter, private slist {

  slink* current_elem;

  public:

     T* first();

     T* next();

     slist_iter() : current_elem(0) { }

};

 

class input_iter : public iter {

  isstream& is;

  public:

     T* first();

     T* next();

     input_iter(istream& r) : is(r) { }

};

Можно таким образом использовать определенные нами типы:

void user(const iter& it)

{

  for (T* p = it.first(); p; p = it.next()) {

     // ...

  }

}

 

void caller()

{

  slist_iter sli;

  input_iter ii(cin);

  // заполнение sli

  user(sli);

  user(ii);

}

Мы применили конкретный тип для реализации абстрактного типа, но можно использовать его и независимо от абстрактных типов или просто вводить такие типы для повышения эффективности программы, см. также $$13.5. Кроме того, можно использовать один конкретный тип для реализации нескольких абстрактных типов.

В разделе $$13.9 описывается более гибкий итератор. Для него зависимость от реализации, которая поставляет подлежащие итерации объекты, определяется в момент инициализации и может изменяться в ходе выполнения программы.




- Начало -  - Назад -  - Вперед -



Книжный магазин