В C++ имеется легкий способ определения оператора вставки для создаваемых классов. В следующем простом примере создается оператор вставки для ранее уже встречавшегося класса point:
class point
{
public:
int x, у, z;
point(int a, int b, int с) { x=a; y=b; z=c; }
}
Для того, чтобы определить оператор вставки для объекта класса point, необходимо перегрузить оператор << по отношению к этому классу. Один из способов показан ниже.
// вывод координат x, y, z (оператор вставки для point)
Многие особенности этой функции являются общими для всех функций вставки. Прежде всего, обратим внимание, что в качестве возвращаемого значения этой функции объявлен объект типа ostream. Это необходимо для того, чтобы один оператор мог содержать несколько операторов вставки. Далее, функция имеет два параметра. Первым служит ссылка на поток, который фигурирует в левой части оператора <<. Вторым параметром служит объект с правой стороны оператора <<. В самой функции осуществляется вывод трех величин, содержащихся в объекте point, после чего возвращается поток stream. Следующая короткая программа служит для демонстрации оператора вставки:
Остается только определить конкретные действия, выполняемые таким оператором вставки. Обратим внимание на необходимость возвращать поток. Также общей практикой является передача параметра объект по ссылке, поскольку если объект является большим, то гораздо быстрее передать его адрес. Также это предотвращает вызов деструктора объекта когда функция вставки возвращает результат.
В программе перегруженная функция вставки не является членом класса point. Действительно, ни функция вставки, ни функция извлечения не могут быть членами класса. Причина заключается в том, что если функция-оператор является членом класса, то левым операндом, неявно передаваемым с использованием указателя this, служит объект того класса, который осуществляет вызов функции-оператора. И нет способа изменить такой порядок. Вместе с тем при перегрузке оператора вставки левым аргументом является поток, а правым аргументом — объект. Поэтому перегруженные операторы вставки не могут быть функциями-членами. Этот факт вызывает логичный вопрос: как перегруженный оператор вставки может получить доступ к частным членам класса? В предыдущей программе переменные x, y и z были публичными, так что оператор вставки имел к ним доступ. Однако защита данных является одной из важнейших особенностей объектно-ориентированного программирования, и требовать, чтобы все данные были публичными, значит противоречить самому духу ООП. Тем не менее, данная проблема имеет решение: оператор вставки может быть другом класса. В качестве друга класса, для которого он определен, он имеет доступ к частным данным. Иллюстрация этого приводится в следующем примере:
#include <iostream.h>
class point
{
int x, y, z; // теперь частные
public:
point(int a, int b, int c) { x=a; y=b; z=c; }
friend ostream& operator<<(ostream &stream, point &obj);
Обратим внимание, что переменные x, у и z являются в данном случае частными членами класса point, но тем не менее продолжают быть доступными непосредственно с помощью функции вставки. Объявление операторов вставки и извлечение друзьями классов, для которых они определены, позволяет сохранить неприкосновенным принцип инкапсуляции объектно-ориентированного программирования.