Системы ввода/вывода С и C++ имеют одну общую особенность: они обе оперируют потоками. То, что потоки в С и C++ подобны между собой, означает, что все, что известно о потоках в языке С, полностью применимо и в C++.
7.1.2 Предопределенные потоки C++
Как и в языке С, в C++ существует несколько предопределенных потоков, открывающихся автоматически вместе с началом выполнения программы. Ими служат cin, cout, cerr и clog. Как известно, cin является потоком, ассоциированным со стандартным вводом, a cout представляет собой поток, ассоциированный со стандартным выводом. Потоки cerr и clog используются для вывода сообщений об ошибках. Разница между cerr и clog заключается в том, что, хотя они оба привязаны к стандартному выводу, cerr не буферизирован, поэтому все посланные в него данные выводятся немедленно. В противоположность этому clog буферизирован, так что данные выводятся только тогда, когда буфер оказывается полным.
По умолчанию стандартные потоки C++ привязаны к консоли, но программа может перенаправить их на другие устройства или файлы. Они также могут быть перенаправлены операционной системой.
7.2 Классы потоков C++
C++ обеспечивает поддержку системы ввода/вывода в заголовочном файле iostream.h. В этом файле определены две иерархии классов, поддерживающие операции ввода/вывода. Классом нижнего уровня является streambuf. Этот класс обеспечивает базовые операции ввода/вывода. До тех пор, пока не вводятся свои собственные классы ввода/вывода, непосредственно streambuf не используется. Вторая иерархия классов начинается с класса ios. Он обеспечивает поддержку форматированного ввода/вывода. От него порождены классы istream, ostream и iostream. Эти классы использованы для создания потоков, способных осуществлять ввод, вывод и ввод/вывод соответственно. Как будет показано далее, от класса ios порождено много других классов, поддерживающих файлы на диске и форматирование в памяти.
В предыдущих главах создаваемые функции-члены классов осуществляли вывод и ввод данных класса с помощью вызова функций наподобие show_data() или get_data(). Хотя технически здесь нет ничего неправильного, язык C++ предоставляет гораздо более совершенный способ выполнения операций ввода/вывода классов с помощью перегрузки операторов << и >>.
На языке C++ оператор << называют оператором вставки (insertion), потому что он вставляет символы в поток. Аналогичным образом оператор >> называется оператором извлечения (extraction), поскольку он извлекает символы из потока. Операторы, перегружающие эти операторы вставки и извлечения, обычно называют инсертером (inserter) и экстрактором (extractor) соответственно. Базовые операторы вставки и извлечения перегружаются в файле iostream.h для того, чтобы выполнять потоковый ввод/вывод любых встроенных типов C++. В этом разделе объясняется, каким образом определить эти операторы по отношению к собственным классам.