|
Программирование >> Операторы преобразования типа
состояния потока данных, игнорировании пропусков и т. д.), а также дополнительных задач, зависящих от реализации. Например, в многопоточных средах, то есть в средах с несколькими параллельно функционирующими потоками выполнения (threads), такой задачей может быть блокировка доступа. Для входных потоков данных при конструировании объекта sentry может передаваться необязательный логический признак, который указывает, что пропуски должны читаться даже при установленном флаге skipws: sentry se(strm.true); Не игнорировать пропуски при чтении Следующий пример демонстрирует эту возможность для класса Row, представляющего строку в текстовом редакторе. О Оператор выводит строку функцией writeQ класса потока данных: std::ostream& operator (std:lOstreamS strm. const Row& row) { Организация предварительной и завершающей обработки std::ostream-.:sentry se(strm): if (se) { Выполнение вывода strm.wrlte(row.c str().row.len()); return strm: О Оператор >> в цикле читает строку по символам. Конструктору объекта sentry передается аргумент true, чтобы пропуски не игнорировались при вводе: std::istream& operator (std::1stream& strm. Row& row) { /* Организация предваритепьной и завершающей обработки * - true: пропуски не игнорируются */ std::1stream::sentry se(stnn.true): If (se) { Выполнение ввода char С: row.clearO; while (strm.get(c) && с != \n) { row.append(c): return strm: Очевидно, что эта архитектура может использоваться даже в том случае, если реализация основана не на вызове функций неформатированного ввода-вывода, а на применении операторов. Тем не менее использование членов классов basicjstream или basic ostream для чтения илн записи символов внутри кода, за- щищенного объектами sentry, малоэффективно. По возможности следует использовать соответствующий объект baslc streambuf. 1ользовательские форматные флаги При определении пользовательских операторов ввода-вывода часто бывает удобно определить для этих операторов специальные форматные флаги (вероятно, устанавливаемые при помощи соответствзтащих манипуляторов). Например, было бы неплохо, если бы приведенный выше оператор вывода дробей можно было настроить иа отделение пробелами числителя и знаменателя от символа /. Объекты потоков данных предоставляют такую возможность - в них предусмотрен механизм связывания данных с потоком. Он позволяет задать нужные значения (например, при помощи манипулятора) и прочитать их позднее. В классе los base определены две функции iword() и pword(), которые при вызове получают индекс типа Int и возвращают по нему соответствующее значение long8i и vold*8i. Предполагается, что iword() и pword() обращаются к объектам long или void* в массиве произвольного размера, хранящемся в объекте потока данных. Форматные флаги, сохраняемые для потока, располагаются по одному и тому же индексу для всех потоков. Статическая функция ха11ос() класса ios base используется для получения индекса, который еще не применялся для этой цели. В исходном состоянии объекты, доступ к которым осзществляется функциями IwordO и pword(), равны 0. Это значение может интерпретироваться и как представление форматирования по умолчанию, и как признак того, что данные еще не инициализировались. Пример: Получение индекса для новых данных ostream static const int iwordjndex - std: :los base: :хаПос(): Определение манипулятора для модификации этих данных std::ostream& fract1on spaces (std::ostream& strm) strm.iword(1word 1ndex) - true: return strm: std::ostream& operator (std::ostream& strm. const Fractions f) { /* Запросить данные у ostream * - true: использовать пробелы между числителем и знаменателем * - false: выводить без пробелов */ if (stem.lworddwordjndex)) { strm f.numeratorO / f. denominator О; else { strm f.numeratorO / f.denominatorО: return strm; В этом примере используется упрощенный подход к реализации оператора вывода, поскольку его основная цель - демонстрация функции Iword(). Форматный флаг считается логическим признаком, определяющим необходимость вывода пробелов между числителем и знаменателем. В первой строке функция los base;:xalloc() возвращает индекс, который может использоваться для хранения форматного флага. Результат вызова сохраняется в константе, так как это значение не модифицируется. Функция fractlon spaces() представляет собой манипулятор для установки значения Int, хранящегося по индексу Iwordjndex в целочисленном массиве, связанном с потоком данных strm. Оператор вывода получает это значение и выводит дробь в соответствии с состоянием флага. Если флаг равен false, по умолчанию дробь выводится без пробелов, а если нет - символ / окружается двумя пробелами. Функции IwordO и pwordO возвращают ссылки на Int или void*. Эти ссылки остаются действительными только до следующего вызова lword() или pword() с соответствующим объектом потока данных нли до уничтожения объекта потока. Обычно результаты lword() и pwordQ сохраняться не должны. Предполагается, что доступ происходит достаточно быстро, хотя представление данных в виде массива не гарантировано. Функция copyfmtO копирует всю форматирующую информацию (см. с. 591), в том числе и массивы, с которыми работают функции lword() и pword(). Это может вызвать проблемы для объектов, сохраняемых в контексте потока данных при помощи pword(). Например, если значение представляет собой адрес объекта, то вместо объекта будет скопирован только адрес. Как следствие, смена формата в одном потоке данных будет распространяться на другие потоки. Также может быть желательно, чтобы объект, ассоциированный с потоком данных функцией pword(), уничтожался при уничтожении потока. Следовательно, для таких объектов желательно реализовать глубокое копирование вместо поверхностного . Для подобных целей (например, реализации глубокого копирования в случае необходимости или удаления объекта при уничтожении потока данных) в los base определен механизм обратного вызова. Функция reglster callback() регистрирует функцию, вызываемую при выполнении определенных условий для объекта ios base. Функция определяется следующим образом: namespace std { class los base { public: Разновидности событий обратного вызова enum event { erase event. imbue event. copyfmt event }: Тип функции обратного вызова typedef void (* event callback) (event e. 1os base& strm. int arg): Регистрация функций обратного вызова void register callback (event callback cb. 1nt arg): }
|
© 2006 - 2025 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |