мы определяем эту связь внутри
Класс
Persist является дружественным классу
Queue; мы определяем эту связь внутри описания класса
Queue следующим образом:
friend class Persist<Item, Queue<Item>>;
В этом случае классы становятся дружественными только в момент инстан-цирования класса
Queue. Внедрив подобные описания дружественности в каждый абстрактный базовый класс, мы обеспечиваем возможность использования
Persist с любой структурой библиотеки.
Параметризованный класс
Persist содержит операции записи и считывания
put и
get, а также функции для подключения потоков обмена данными. Мы можем определить данную абстракцию следующим образом:
template<class Item, class Structure>
class Persist {
public: Persist();
Persist(iostream& input, iostream& output);
virtual ~Persist();
virtual void setInputStream(iostream&);
virtual void setOutputStream(iostream&);
virtual void put(Structure&);
virtual void get(Structure&);
protected: iostream* inStreain;
iostream* outStream;
};
Рис. 9-14. Обеспечение сохраняемости с помощью агента.
Реализация данного класса зависит от того, является ли он дружественным классу Structure, который фигурирует в качестве аргумента шаблона. В частности,
Persist зависит от наличия в структуре вспомогательных функций purge,
cardinality,
itemAt,
lock, и
unlock. Далее срабатывает однородность нашей библиотеки: поскольку каждый базовый класс Structure имеет подобные функции, то
persist можно безо всяких изменений использовать для работы со всеми имеющимися в библиотеке структурами.
Рассмотрим в качестве примера реализацию функции
Persist::put:
template<class Item, class Structure>
void Persist<Item, Structure>::put(Structure& s)
{ s.lock();
unsigned int count = s.cardinality();
(*outStream) << count << endl;
for (unsigned int index = 0; index < count; index++) (*outStream) << s.itemAt(index);
s.unlock();
}
Эта операция использует разработанный нами ранее механизм блокировки, поэтому она будет работать и для защищенных, и для синхронизированных форм.
Содержание Назад Вперед