ГЛАВА 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.