Шаг 20.
Перегрузка стандартных операций (окончание). Операции "++" и "--"

    На этом шаге мы рассмотрим особенности перегрузки операций "++" и "--".

    В отличие от всех других унарных операций операции "++" и -- имеют, кроме префиксной формы еще и постфиксную. Это привело к особенностям при их перегрузке. В начальных версиях языка 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.

    Со следующего шага мы начнем рассматривать механизм наследования.




Предыдущий шаг Содержание Следующий шаг