Спроектировать библиотеку ввода/вывода, основанную на применении паттерна Decorator. Центральным элементом библиотеки должен быть интерфейс потока. Этот интерфейс должен реализовываться в нескольких конкретных классах, предназначенных для записи на различные устройства (в файл, в память, в строку). Должна быть возможность применения модификаторов (буферирование, кодирование, сжатие) к любому потоку, причем, следует учесть, что к потоку может применяться произвольное количество модификаторов. Предусмотреть также возможность определения пользователем библиотеки собственных модификаторов потока, и обеспечить удобное их использование, наряду с имеющимися изначально в проекте.
Замечание | |
---|---|
Все перечисленные задачи решаются правильным применением паттерна Decorator. Фактически, Вам необходимо выделить нужные классы, и определить роль каждого класса в паттерне. |
Необходимо реализовать те классы, которые непосредственно отвечают за вывод в файл и буферирование потока. Кроме того, нужно реализовать классы для записи в поток значений некоторых встроенных типов (целых чисел, вещественных чисел, строк - выбрать два из трех).
Интерфейс потока вывода должен включать, как минимум, две операции: побайтовый вывод, и вывод последовательности байт заданного размера.
На самом нижнем уровне вывод осуществлять с помощью функций open()
,
read()
,write()
,close()
, описанных в
заголовочном файле io.h
.
При возникновении ошибки (например, невозможности записи в поток) следует генерировать исключение
(exception), причем, лучше всего, если класс
исключения будет производным от std::exception
.
Для защиты лабораторной работы необходимо представить:
Разработанная библиотека должна допускать подобное использование:
/*...*/ int main() { /* Создается поток записи в файл (FileStream) и настраивается * на работу с файлом "output.txt". * Создается экземпляр BufferedStream, добавляющий буферизацию * для связанного с ним потока. Непосредственно при создании * BufferedStream связывается с экземпляром FileStream * (в данном случае, указатель на созданный FileStream просто * передается конструктору BufferedStream в качестве аргумента). */ OutputStream *os = new BufferedStream( new FileStream("output.txt") ); os->write('l'); // вывод в поток одного символа os->write("ab4\n", 4); // вывод в поток указанного количества // символов // Создаем экземпляр класса для вывода значений встроеных типов // и связываем его с созданным ранее потоком. DataWriter *dw = new DataWriter(os); dw->write(15); // вызов перегруженной операции write() dw->write("Hello, world!\n"); // вызов перегруженной операции write() delete dw; delete os; return 0; }