- •Объектно-ориентированное программирование:
- •Содержание
- •Новый тип данных – класс
- •1.2. Доступность компонентов класса
- •1.3. Конструктор и деструктор
- •1.4.4. Статические члены класса
- •1.4. Компоненты-данные и компоненты-функции
- •1.4.1. Данные – члены класса
- •1.4.2. Функции – члены класса
- •1.4.3. Константные компоненты-функции
- •Указатели на компоненты класса
- •1.5.1. Указатели на компоненты-данные
- •1.5.2.Указатели на компоненты-функции
- •1.6. Указатель this
- •1.7. Друзья классов
- •7.1. Дружественная функция
- •1.7.2. Дружественный класс
- •1.8. Определение классов и методов классов
- •2. Наследование
- •2.1. Определение производного класса
- •2.2. Конструкторы и деструкторы производных классов
- •2.3. Виртуальные функции
- •2.4. Абстрактные классы
- •2.5. Включение объектов
- •2.6. Включение и наследование
- •2.7. Множественное наследование
- •2.8. Локальные и вложенные классы
- •2.9. Пример программы для Microsoft Visual Studio
- •2.10. Упражнения
- •3. Перегрузка операций
- •3.1. Перегрузка унарных операций
- •3.2. Перегрузка бинарных операций
- •3.4. Перегрузка операции вызова функции
- •3.5. Перегрузка операции присваивания
- •3.6. Перегрузка операции new
- •3.7. Перегрузка операции delete.
- •3.8. Основные правила перегрузки операций
- •3.9. Примеры программ
- •4. Шаблоны функций и классов
- •4.1. Шаблоны функций
- •4.2. Шаблоны классов
- •4.3. Компонентные функции параметризованных классов
- •4.4. Примеры программ.
- •5. Обработка исключительных ситуаций
- •5.2. Получение дополнительной информации об исключении
- •5.3. Определение типа исключения
- •5.4. Иерархия исключений
- •5.5. Спецификация функций, обрабатывающих исключения
- •6. Потоковые классы
- •6.1. Библиотека потоковых классов
- •6.3. Стандартные потоки ввода-вывода
- •6.4. Форматирование
- •6.5. Манипуляторы
- •6.6. Ввод-вывод объектов пользовательских классов
- •6.7. Определение пользовательских манипуляторов
- •6.8. Пользовательские манипуляторы с параметрами
- •6.9. Использование макросов для создания манипуляторов
- •6.10. Состояние потока
- •6.11. Неформатированный ввод-вывод
- •6.12. Файловый ввод-вывод
- •7.1. Пространство имен
- •7.2. Динамическая идентификация типов
- •7.3. Безопасное приведение типа
- •8. Стандартная библиотека шаблонов
- •8.1. Введение в stl
- •Парадигму обобщенного программирования можно сформулировать следующим образом:
- •8.2. Итераторы
- •8.3. Классы-контейнеры
- •Iterator find(const key_type&k)
- •Iterator lower_bound(const key_type&k)
- •Iterator upper_bound(const key_type&k)
- •8.4. Контейнер vector
- •8.5. Многомерные массивы
- •8.6. Ассоциативные контейнеры
- •8.7. Объекты-функции
- •8.8. Алгоритмы
- •I. Немодифицирующие операции
- •II. Модифицирующие операции
- •III. Сортировка
- •IV. Работа с множествами
- •V. Минимумы и максимумы
- •VI. Перестановки
6. Потоковые классы
6.1. Библиотека потоковых классов
Потоковые классы представляют объектно-ориентированный вариант библиотечных функций ввода-вывода C. Поток данных между источником и приемником при этом обладает следующими свойствами:
Источник или приемник данных определяется объектом потокового класса.
Потоки используются для ввода-вывода высокого уровня.
Общепринятые стандартные С-функции ввода/вывода разработаны как методы потоковых классов, чтобы облегчить переход от С-функций к С++ классам.
Потоковые классы опредены как шаблоны и делятся на три группы :
basic_istream, basic_ostream – общие потоковые классы, которые могут быть связаны с любым буферным объектом;
basic_ifstream, basic_iostream – потоковые классы для считывания и записи файлов;
basic_istringstream, basic_ostringstream – потоковые классы для объектов-строк.
Каждый потоковый класс поддерживает буферный объект, который предоставляет память для передаваемых данных, а также важнейшие функции ввода/вывода низкого уровня для их обработки.
Базовым шаблоном классов basic-ios (для потоковых классов) и basic-streambuf (для буферных классов) передаются по два параметра шаблона:
первый параметр (charT) определяет символьный тип;
второй параметр (traits) – объект типа ios-traits (шаблон класса), в котором заданы тип и функции, специфичные для используемого символьного типа;
для типов char и wchar_t образованы соответствующие объекты типа ios_traits и потоковые классы.
Например, шаблон класса для потокового ввода определен следующим образом:
template <class charT, class traits = ios_traits <charT>> class basic_istream: virtual public basic_ios <charT, traits>;
6.2. Ввод-вывод в языке С++
Ввод-вывод – одна из самых сложных областей любого языка. Она тесно связана и с операционной системой, и с оборудованием.
Система ввода-вывода, принятая в ANSI, хороша, но не идеальна. Она не учитывает огромной разницы между устройствами с точки зрения программиста. Все устройства можно разделить на блочные и символьные. Например, диски и ленты – это блочные устройства, тогда как терминалы – символьные. Блочные устройства для эффективного чтения-записи требуют буферизации , а символьные в ней не нуждаются. Устройства ввода-вывода имеют и много других различий. В библиотеку С (stdio.h) были введены некоторые исключения для обработки специальных устройств. В конце 60-х годов обращение к устройствам как к файлам было новинкой. Однако в большинстве случаев программист не работает с устройствами как с файлами. Это приводит к добавлению в С новых функций, поскольку иногда программист должен знать, работает он с дисковым файлом или с устройством.
Существует множество примеров того, что функции, применяемые к устройствам, а не к нормальным файлам, ведут себя по-разному, а иногда и некорректно.
С++ не первый язык, работающий с потоками. ANSI C использует так называемые потоки для указания на некоторый абстрактный порт, через который могут передаваться неструктурированные данные. В ANSI С поток рассматривается как конструкция ввода-вывода низкого уровня, на которую наслаивается более структурированная файловая система.
В С++ потоки реализованы через целую иерархию классов, которая является единственной основной иерархией, поставляемой со всеми компиляторами языка С++.
В С++ потоки составляют некую оболочку, которая придает операциям ввода-вывода полиморфные и объектно-ориентированные свойства. Несмотря на то, что потоки часто ассоциируются с вводом-выводом, реально они являются абстракцией передачи данных от одного объекта к другому с помощью механизма буферизации. Это означает, что любая функция, используемая для передачи данных из одного места в памяти в другое (с изменением данных или без такового), может рассматриваться как потоковая операция.
Библиотека потоковых классов С++ построена на основе двух базовых классов: ios и streambuf .
Класс streambuf и его потомки обеспечивают организацию и взаимосвязь буферов ввода-вывода, размещаемых в памяти, с физическими устройствами ввода-вывода. Методы и данные класса streambuf программист явно обычно не использует. Этот класс нужен другим классам библиотеки ввода-вывода. Он доступен и программисту для создания новых классов на основе уже существующих.
streambuf
filebuf
conbuf
strstreambuf
Рис. 6.1. Иерархия буферных классов
Класс ios и его потомки содержат средства для форматированного ввода-вывода и проверки ошибок.
ios
istream
ostream
strstreambase
fstreambase
ifstream
ostrstream
fstream
strstream
iostream
istrstream
ofstream
Рис. 6.2. Иерархия классов ввода-вывода
Потоковые классы, их методы и данные становятся доступными в программе, если в неё включен нужный заголовочный файл.
Итак, потоки С++ обеспечивают:
буферизацию при обменах с внешними устройствами;
независимость программы от файловой системы конкретной ЭВМ;
контроль типов передаваемых данных;
возможность удобного обмена для типов, определенных пользователем.
