На этом шаге мы рассмотрим особенности использования этого оператора.
В С и C++ операторы << и >> используются для сдвига битов целых чисел вправо и влево. Классы basic_istream и basic_ostream перегружают операторы >> и << для выполнения стандартных операций ввода-вывода.
Класс basic_ostream (а следовательно, и классы ostream и wstream) интерпретирует << как оператор вывода. Он перегружает этот оператор для всех базовых типов, включая char*, void и bool.
В соответствии с определением операторов потокового вывода второй аргумент передается в соответствующий поток данных. Иначе говоря, данные пересылаются в направлении "стрелки":
int i = 7; std::cout << i; // Вывод: 7 float f = 4.5; std::cout << f; // Вывод: 4.5
Оператор << перегружается так, что второй аргумент может относиться к произвольному типу данных. Это позволяет интегрировать ваши типы данных с системой ввода-вывода. Компилятор следит за тем, чтобы для вывода второго аргумента была вызвана правильная функция. Конечно, эта функция должна преобразовать второй аргумент в последовательность символов, выводимых в поток данных.
В стандартной библиотеке C++ этот механизм также применяется при выводе строк (смотри 407 шаг), битовых полей (357 шаг) и комплексных чисел (418 шаг):
std::string s("hello"); s += ", world"; std::cout << s; // Вывод: hello, world std::bitset<10> flags(7); std::cout << flags; // Вывод: 0000000111 std::complex<float> c(3.1,7.4); std::cout << с; // Вывод: (3.1,7.4)
Возможность расширения механизма вывода для поддержки пользовательских типов данных является существенным усовершенствованием по сравнению с механизмом ввода-вывода языка С, основанным на использовании функции printf(), поскольку больше не требуется указание типа выводимого объекта. Перегрузка оператора для различных типов гарантирует, что правильная функция вывода будет выбрана автоматически. Оператор << не ограничивается стандартными типами. Таким образом, в распоряжении программиста появляется единый механизм вывода, работающий со всеми типами.
Оператор << также может использоваться для вывода нескольких объектов в одной команде. По общепринятым правилам операторы вывода возвращают свой первый аргумент, то есть результатом выполнения оператора вывода является выходной поток данных. Это позволяет объединять вызовы операторов вывода в цепочки вида:
std::cout << х << " times " << у << " is " << х * у << std::endl;
Цепочечные вызовы оператора << обрабатываются слева направо. Так, в приведенном примере первой будет выполнена следующая команда:
std::cont << x
Учтите, что это правило не распространяется на порядок вычисления аргументов, - оно определяет только порядок выполнения операторов вывода. Выражение возвращает свой первый операнд std::cout. Следующей будет выполнена команда:
std::cout << " times "
Далее последовательно выводятся объект у, строковый литерал " is " и результат операции х*у. Оператор умножения обладает более высоким приоритетом, чем оператор <<, поэтому выражение х*у не нужно заключать в скобки, однако существуют операторы с более низким приоритетом (например, все логические операторы). Если в данном примере х и у - вещественные числа со значениями 2.4 и 5.1, будет выведена следующая строка:
2.4 times 5.1 is 12.24
На следующем шаге мы рассмотрим оператор ввода.