Язык программирования C++ от Страуструпа

       

ВЫВОД


Строгую типовую  и  единообразную  работу как со встроенными,  так и с пользовательскими типами  можно  обеспечить,  если использовать единственное перегруженное имя функции для различных операций вывода. Например:

put(cerr,"x = "); // cerr - выходной поток ошибок

put(cerr,x);

put(cerr,'\n');

Тип аргумента определяет какую функцию надо вызывать в каждом случае.

Такой подход применяется в нескольких языках, однако, это слишком длинная запись. За счет перегрузки операции << , чтобы она означала "вывести" ("put to"), можно получить более простую запись и разрешить программисту выводить в одном операторе последовательность объектов, например так:

cerr << "x = " << x << '\n';

Здесь cerr обозначает стандартный поток ошибок. Так, если х типа int со значением 123, то приведенный оператор выдаст

x = 123

и еще символ конца строки в стандартный поток ошибок. Аналогично, если х

имеет пользовательский тип complex со значением (1,2.4), то указанный оператор выдаст

x = (1,2.4)

в поток cerr. Такой подход легко использовать пока x такого типа, для

которого определена операция <<,  а пользователь может просто доопределить << для новых типов.

Мы использовали операцию вывода, чтобы избежать многословности, неизбежной, если применять функцию вывода. Но почему именно символ << ? Невозможно изобрести новую лексему (см.  7.2).  Кандидатом для ввода и вывода была операция присваивания, но большинство людей предпочитает, чтобы операции ввода и вывода были различны. Более того, порядок выполнения операции = неподходящий, так cout=a=b означает cout=(a=b). Пробовали использовать операции < и >, но к ним так крепко привязано понятие "меньше чем" и "больше чем", что операции ввода-вывода с ними во всех практически случаях не поддавались прочтению.

Операции << и >> похоже не создают таких проблем. Они асиметричны,

что позволяет приписывать им смысл "в" и "из". Они не относятся к числу наиболее часто используемых операций над встроенными типами, а приоритет << достаточно низкий, чтобы писать арифметические выражения в качестве операнда без скобок:

cout << "a*b+c=" << a*b+c << '\n';

Скобки нужны, если выражение содержит операции с более низким приоритетом:

cout << "a^b|c=" << (a^b|c) << '\n';

Операцию сдвига влево можно использовать в операции вывода, но, конечно, она должна быть в скобках:

cout << "a<<b=" << (a<<b) << '\n';



Содержание раздела