Бьерн Страуструп - Язык программирования С++. Главы 5-7 - Глава 7. Перегрузка операций

ОГЛАВЛЕНИЕ

ГЛАВА 7. Перегрузка операций


  Если я выбираю слово, оно значит только то,
  что я решу, ни больше и ни меньше.
                       - Шалтай Болтай

Глава содержит описание механизма перегрузки операций в С++.

Программист может задать интерпретацию операций, когда они применяются к объектам определенного класса. Помимо арифметических, логических и операций отношения можно переопределить вызов функций (), индексацию [], косвенное обращение ->, а также рисваивание и инициализацию. Можно определить явные и скрытые преобразования между пользовательскими и основными типами. Показано, как определить класс, объект которого можно копировать и ничтожать только с помощью специальных, определенных пользователем функций.

7.1 Введение

Обычно в программах используются объекты, являющиеся конкретным представлением абстрактных понятий. Например, в С++ тип данных int вместе с операциями +, -, *, / и т.д. реализует (хотя и ограниченно)
математическое понятие целого. Обычно с понятием связывается набор действий, которые реализуются в языке в виде основных операций над объектами, задаваемых в сжатом, удобном и привычном виде. К сожалению, в языках программирования непосредственно представляется только малое число понятий. Так, понятия комплексных чисел, алгебры матриц, логических сигналов и строк в С++ не имеют непосредственного выражения. Возможность задать представление сложных объектов вместе с набором операций, выполняемых над такими объектами, реализуют в С++ классы. Позволяя программисту определять операции над объектами классов, мы получаем более удобную и традиционную систему обозначений для работы с этими объектами по сравнению с той, в которой все операции задаются как обычные функции. Приведем пример:
         class complex {
           double re, im;
         public:
           complex(double r, double i) { re=r; im=i; }
           friend complex operator+(complex, complex);
           friend complex operator*(complex, complex);
        };
Здесь приведена простая реализация понятия комплексного числа, когда оно представлено парой чисел с плавающей точкой двойной точности, с которыми можно оперировать только с помощью операций + и *. Интерпретацию этих операций задает программист в определениях функций с именами operator+ и operator*. Так, если b и c имеют тип complex, то b+c означает (по определению) operator+(b,c). Теперь можно приблизиться к привычной записи комплексных выражений:
       void f()
       {
         complex a = complex(1,3.1);
         complex b = complex(1.2,2);
         complex c = b;

         a = b+c;
         b = b+c*a;
         c = a*b+complex(1,2);
       }
Сохраняются обычные приоритеты операций, поэтому второе выражение выполняется как b=b+(c*a), а не как b=(b+c)*a.