Выбрать главу

В языке C++ оператор "<<" называется оператором вывода или вставки, поскольку он вставляет символы в поток. Аналогично оператор ">>" называется оператором ввода или извлечения, поскольку он извлекает символы из потока.

Как вы знаете, операторы ввода-вывода уже перегружены (в заголовке <iostream>), чтобы они могли выполнять операции потокового ввода или вывода данных любых встроенных С++-типов. Здесь вы узнаете, как определить эти операторы для собственных классов.

Создание перегруженных операторов вывода

В качестве простого примера рассмотрим создание оператора вывода для следующей версии класса 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.

Перед вами короткая программа, в которой демонстрируется использование оператора вывода.

// Использование перегруженного оператора вывода.

#include <iostream>

using namespace std;

class three_d {

 public:

  int x, y, z; // 3-мерные координаты

  three_d(int a, int b, int с) { x = a; у = b; z = c; }

};

/* Отображение координат X, Y, Z (оператор вывода для класса three_d).

*/

ostream &operator<<(ostream &stream, three_d obj)

{

 stream << obj.x << ", ";

 stream << obj.у << ", ";

 stream << obj.z << "\n";

 return stream; // возвращает параметр stream

}

int main()

{

 three_d a(1, 2, 3), b(3, 4, 5), c(5, 6, 7);

 cout << a << b << c;

 return 0;

}

При выполнении эта программа возвращает следующие результаты:

1, 2, 3

3, 4, 5

5, 6, 7

Если удалить код, относящийся конкретно к классу three_d, останется "скелет", подходящий для любой функции вывода данных.

ostream &operator<<(ostream &stream, class_type obj)

{

 // код, относящийся к конкретному классу

 return stream; // возвращает параметр stream

}

Как уже отмечалось, для параметра obj разрешается использовать передачу по ссылке. В широком смысле конкретные действия функции вывода определяются программистом. Но если вы хотите следовать профессиональному стилю программирования, то ваша функция вывода должна все-таки выводить информацию. И потом, всегда нелишне убедиться в том, что она возвращает параметр stream.

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

/* Версия ограниченного применения (использованию не подлежит).