С++ Перегрузка бинарных operators << и >>

При работе с консолью мы часто читаем данные с клавиатуры и выводим какие-то данные на экран. Это делается или в стиле Си или в стиле С++. В стиле С++ для чтения данных с клавиатуры используют объект cin и его метод >>,

а для вывода на экран часто используют объект cout и его метод <<

Эти методы (<< и >>) называют операторами или операциями. (от англ. operator). Я не буду говорить как правильно, уже заварилась такая каша, что понимать надо всё из контекста. В остальном они ведут себя точно также, как ведут себя обычные функции, но с ограничениями в написании параметров. Количество задаваемых параметров зависит от вида операции. Существует три вида: унарная, бинарная, тернарная.

Было время, что я долго не мог понять что это за слова такие дикие.
Унарная — требует одного операнда.
Бинарная — требует двух операндов.
Тернарная — требует трёх операндов.

Под операндом можно понимать любой объект какого-то типа.

Для перегрузки остаются только унарные и бинарные операции. Операция "Поместить в поток" >> аналогична операции "Взять из потока" в том плане, что требует два операнда.

Очень простой вариант перегрузки, от которого произойдёт дальнеёшее изложение, выглядит так:

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

При этом можно обратиться как к параметров объекта, находящегося слева от операции <<, так и к параметрам справа от неё.

Вывестись должны 5 и 10, соответственно. Тот операнд, который находится слева от операции <<, воспринимается как родной, а тот операнд, который справа — воспринимается как пришедший параметр, и, следовательно, нужно для доступа к данным использовать параметр, а уже через параметр обращаться к его элементам. Это и было сделано.

Сейчас уже можно поместить данные одного объекта в данные другого объекта не при помощи операции =, а при помощи операции <<.

Главное описывать правильно тело при перегрузке оператора. Ведь описать там можно очень многое.

  • Всегда помните, что перегрузка нужна для облегчения написания кода. Не нужно перегружать всё подряд как попало, нужно перегружать так, чтобы путанницы перегрузка не порождала. Например, если бы я перегрузил поведение операции << таким образом, чтобы она считала сумму в этом примере, то что-то типа
    только усложнило бы всё, и это не есть хорошо.
  • Перегрузка операторов, это всего лишь более удобный способ вызова функций, поэтому не стоит увлекаться перегрузкой операторов. Использовать её следует только тогда, когда это упростит написание кода. Но, не настолько, чтобы это затрудняло чтение

По той причине, что работа происходила с объектами одного класса, достаточно было указать один параметр и работать с тем, что есть. Но иногда требуется работать с объектами разных классов. В таком случае указывают два параметра, а кроме того, может быть необходимо добавить ключевое слово friend. Очень распространённая необходимость — работа объектов с файлами. Файловый объект — это объект одного класса, а у нас свой класс, и мы хотим заполнить объект своего класса данными из файла. Можно написать много кода, много функций, но это не способствует облегчению чтения, а способствует только громоздкости кода. При обычной работе с файлами мы берём данные из потока с помощью операции << или записываем данные в поток >>. При работе с клавиатурой мы используем объект cin, а для вывода на экран cout, в случае с файлами мы используем объекты таких же типов:
cin имеет тип istream
cout имеет тип ostream

Эти объекты — это потоки, только потоки либо ввода, либо вывода. Ввод — один тип, вывод — другой тип.

Объекты разных классов — объекты разные. Объект нашего класса — это отдельный объект от объектов cin или cout и других. Чтобы наш класс работал с объектами, которые потоки, и при этом таким же образом как, например клавиатура работает с монитором

необходимо понимать к какому типу принадлежит объект, с которым мы взаимодействуем. Вот хотим мы ввести данные в объект нашего класса с клавиатуры, да чтобы также просто как в какой-нибудь объект типа int:

Нужно для нашего собственного класса перегрузить операцию >>, делается это немного иначе, чем выше показано.

Аналогичным образом делается это для <<

Всё теперь стало удобно. Очень важен тот момент, что как в возвращаемом значении, так и в параметрах перегружаемой операции используются ссылки. Использование ссылок в параметрах необходимо для того, чтобы изменения сохранились. Иначе внутри функции создадутся локальные копии, работа будет происходить с ними, а по завершению работы функции все эти локальные копии прекратят существование, поэтому никаких изменений заметно не будет. Ну а возвращается не просто какой-то объект, а ссылка на объект какого-то определённого типа. friend необходим по той причине, что сторонний объект обращается к закрытым объектам нашего класса. В примере переменная X из класса MyClass недоступна никому извне, а мы к ней обращаемся извне, когда пишем MyObject.X;

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

При работе с файлом происходит всё в точности также. Принцип везде один. Пример работы с файлом, где из файла заполняется массив структур (В стиле с использованием некоторых возможностей С++11):

Текст файла

Skrebok	   15	  345	 12
Provoda    20 	  200 	 13
Nagr.el.   10	 1600 	  8
Все комментарии на сайте проверяются, поэтому ваш комментарий может появиться не сразу. Для вставки кода в комментарий используйте теги: [php]ВАШ_КОД[/php]

Добавить комментарий

Ваш e-mail не будет опубликован.

Поиск

 
     
Яндекс.Метрика

НАГРАДИ АВТОРА САЙТА
WEBMONEY
R375024497470
U251140483387
Z301246203264
E149319127674

Демотиватор программирование на языке ада

Выражаю свою признательность

  • Максиму очень признателен за указание на мои ошибки и неточности.
  • Sergio ===> за оказание помощи в исправлении моих ошибок
  • Gen ===> за правильное стремление помочь другим новичкам и выявления моих ошибок