С++-система ввода-вывода построена на двух связанных, но различных иерархиях шаблонных классов. Первая выведена из класса низкоуровневого ввода-вывода basic_streambuf
. Этот класс поддерживает базовые низкоуровневые операции ввода и вывода и обеспечивает поддержку для всей С++-системы ввода-вывода. Если вы не собираетесь заниматься программированием специализированных операций ввода-вывода, то вам вряд ли придется использовать напрямую класс basic_streambuf. Иерархия классов, с которой С++-программистам наверняка предстоит работать вплотную, выведена из класса basic_ios. Это — класс высокоуровневого ввода-вывода, который обеспечивает форматирование, контроль ошибок и предоставляет статусную информацию, связанную с потоками ввода-вывода. (Класс basic_ios выведен из класса ios_base, который определяет ряд нешаблонных свойств, используемых классом basic_ios.) Класс basic_ios используется в качестве базового для нескольких производных классов, включая классы basic_istream, basic_ostream и basic_iostream. Эти классы используются для создания потоков, предназначенных для ввода данных, вывода и ввода-вывода соответственно.Как упоминалось выше, библиотека ввода-вывода создает две специализированные иерархии шаблонных классов: одну для 8-, а другую для 16-битовых символов. Ниже приводится список имен шаблонных классов и соответствующих им "символьных" версий.
В остальной части этой книги используются имена символьных классов, поскольку именно они применяются в программах. Те же имена используются и старой библиотекой ввода-вывода. Вот поэтому старая и новая библиотеки совместимы на уровне исходного кода.
И еще: класс ios
содержит множество функций-членов и переменных, которые управляют основными операциями над потоками или отслеживают результаты их выполнения. Поэтому имя класса ios будет употребляться в этой книге довольно часто. И помните: если включить в программу заголовок , она будет иметь доступ к этому важному классу.Перегрузка операторов ввода-вывода
В примерах из предыдущих глав при необходимости выполнить операцию ввода или вывода данных, связанных с классом, создавались функции-члены, назначение которых и состояло лишь в том, чтобы ввести или вывести эти данные. Несмотря на то что в самом этом решении нет ничего неправильного, в C++ предусмотрен более удачный способ выполнения операций ввода-вывода "классовых"
данных: путем перегрузки операторов ввода-вывода "<<" и ">>".Оператор "<<" выводит информацию в поток, а оператор ">>" вводит информацию из потока.
В языке C++ оператор "<<"
называется оператором вывода или вставки, поскольку он вставляет символы в поток. Аналогично оператор ">>" называется оператором ввода или извлечения, поскольку он извлекает символы из потока.Как вы знаете, операторы ввода-вывода уже перегружены (в заголовке
), чтобы они могли выполнять операции потокового ввода или вывода данных любых встроенных С++-типов. Здесь вы узнаете, как определить эти операторы для собственных классов.Создание перегруженных операторов вывода
В качестве простого примера рассмотрим создание оператора вывода для следующей версии класса three_d
.
class three_d {
public:
int x, у, z; // 3-мерные координаты
three_d(int a, int b, int с) { x = a; у = b; z = c; }
};
Чтобы создать операторную функцию вывода для объектов типа three_d
, необходимо перегрузить оператор "<<". Вот один из возможных способов.
/* Отображение координат X, Y, Z (оператор вывода для класса three_d).
*/
ostream &operator<<(ostream &stream, three_d obj)
{
stream << obj.x << ", ";
stream << obj.у << ", ";
stream << obj.z << "\n";
return stream; // возвращает параметр stream
}
Рассмотрим внимательно эту функцию, поскольку ее содержимое характерно для многих функций вывода данных. Во-первых, отметьте, что согласно объявлению она возвращает ссылку на объект типа ostream
. Это позволяет несколько операторов вывода объединить в одном составном выражении. Затем обратите внимание на то, что эта функция имеет два параметра. Первый представляет собой ссылку на поток, который используется в левой части оператора. Вторым является объект, который стоит в правой части этого оператора. (При необходимости второй параметр также может иметь тип ссылки на объект.) Само тело функции состоит из инструкций вывода трех значений координат, содержащихся в объекте типа three_d, и инструкции возврата потока stream.