На этом шаге мы рассмотрим особенности перегрузки операций "++" и "--".
В отличие от всех других унарных операций операции "++" и -- имеют, кроме префиксной формы еще и постфиксную. Это привело к особенностям при их перегрузке. В начальных версиях языка C++ при перегрузках операций ++ и -- не делалось различия между постфиксной и префиксной формами. Например, в следующей программе действие операции ++ распространено на объекты класса pair с помощью дружественной операции-функции с одним параметром:
friend pair& operator ++ (pair &);
Операция -- перегружена с помощью компонентной операции-функции класса pair, не имеющей параметров:
pair& pair::operator -- ();
В компиляторе ТC++ реализованы первые варианты языка C++, и поэтому он не различает постфиксного и префиксного применений операций "++", "--". Текст программы:
//OOР20_1.СРР - перегрузка унарных операций ++, -. #include <iostream.h> // Класс "пара чисел": class pair { int N; // Целое число. double x; // Вещественное число. // Дружественная функция: friend pair& operator ++ (pair &); public : pair (int n, double xn) // Конструктор. { N = n; x = xn; } void display () { cout << "\nКоординаты: N = " << N << "\tx = " << x; } pair& operator -- () // Компонентная функция. { N -= 1; x -= 1.0; return *this;} }; pair& operator ++(pair& P) // Дружественная функция. { P.N += 1; P.x += 1.0; return P; } void main () { pair Z(10,20.0) ; Z.display() ; ++Z; Z.display(); --Z; Z.display(); Z++; Z.display(); Z--; Z.display(); }
Результат выполнения программы:
Координаты: N = 10 х = 20 Координаты: N = 11 х = 21 Координаты: N = 10 х = 20 Координаты: N = 11 х = 21 Координаты: N = 10 х = 20
Как наглядно демонстрируют результаты, компилятор TC++ не учитывает префиксность и постфиксность перегруженных операций "++" и "--".
В современной версии языка C++ принято соглашение, что перегрузка префиксных операций "++" и "--" ничем не отличается от перегрузки других унарных операций, т.е. глобальные и, возможно, дружественные функции operator ++() и operator --() с одним параметром некоторого класса определяют префиксные операции "++" и "--". Компонентные операции-функции без параметров определяют те же префиксные операции. При расширении действия постфиксных операций "++" и "--" операции-функции должны иметь еще один дополнительный параметр типа int. Если для перегрузки используется компонентная операция-функция, то она должна иметь один параметр типа int. Если операция-функция определена как глобальная (не компонентная), то ее первый параметр должен иметь тип класса, а второй - тип int.
Когда в программе используется соответствующее постфиксное выражение, то операция-функция вызывается с нулевым целым параметром.
В следующей программе иллюстрируются возможности применения разных операций-функций для постфиксной и префиксной операций "++" и "--":
//OOР20_2.СРР - необычная перегрузка унарных операций ++, --. #include <iostream.h> // Класс "пара чисел": class pair { int N; // Целое число. double x; // Вещественное число. // Дружественная функция для префиксной операции: friend pair& operator ++ (pair&); // Дружественная функция для постфиксной операция: friend pair& operator ++ (pair&, int); public: pair (int n, double xn) // Конструктор. { N = n; x = xn; } void display() { cout << "\nКоординаты: N = " << N << " x = " << x; } // Компонентная функция (префиксная --): pair& operator -- () { N /= 10; x /= 10; return *this; } // Компонентная функция (постфиксная --): pair& operator -- (int k) { N /= 2; x /= 2.0; return *this; } }; pair& operator ++ (pair& P) // Префиксная операция ++. { P.N *= 10; P.x *= 10; return P; } // Постфиксная операция ++: pair& operator ++ (pair& P,int k) { P.N = P.N * 2 + k; P.x = P.x * 2 + k; return P; } void main() { pair Z(10,20.0); Z.display(); ++Z; Z.display(); --Z; Z.display(); Z++; Z.display(); Z--; Z.display(); }
Результаты выполнения программы:
Координаты: N = 10 х = 20 Координаты: N = 100 х = 200 Координаты: N - 10 х = 20 Координаты: N = 20 х = 40 Координаты: N = 10 ж = 20
Для демонстрации полной независимости смысла перегруженной операции от ее традиционного (стандартного) значения в операциях-функциях для префиксных операций "++" соответствуют увеличению в 10 раз, а "--" уменьшению в 10 раз. Для постфиксных операций "++" определили как увеличение в 2 раза, а "--" как уменьшение в 2 раза. Попытки использовать в постфиксных операциях-функциях значение дополнительного параметра int k подтверждает его равенство 0.
Со следующего шага мы начнем рассматривать механизм наследования.