Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Lections_rus.doc
Скачиваний:
31
Добавлен:
06.02.2016
Размер:
1.41 Mб
Скачать

5.2. Особенности перегрузки префиксной и постфиксной форм унарных операций

В отличие от всех других унарных операций операции ++ и -- имеют, кроме префиксной формы еще и постфиксную. Это привело к особенностям при их перегрузке.

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

Предположим, мы хотим прибавить 1 к объекту с0 класса С. Когда компилятор встречает выражение с префиксным инкрементом ++c0, он генерирует вызов функции-элемента c0.operator++(), прототип которой должен иметь вид:

C& operator++ ();

Если префиксная форма инкремента реализуется как функция, которая не является функцией-членом класса, то, когда компилятор встречает выражение ++c0, он генерирует вызов функцииoperator++(c0). Прототип такой функции должен быть объявлен в классе С как дружественный:

friend C& operator++(C&);

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

По соглашению, принятому в С++, когда компилятор встречает выражение постфиксной формы инкремента c0++, он генерирует вызов функции с0.operator++(0), прототипом которой является

C& operator++(int).

Нуль (0) в генерируемом вызове функции явялется чисто формальным значением, введенным для того, чтобы сделать список аргументов функции operator++, используемой для постфиксной формы инкремента, отличным от списка агументов функции operator++, используемых для префиксной формы инкремента.

Фиктивный параметр int никогда не используется, а лишь служит признаком того, что функция вызывается для выполнения операции ++ или -- в постфиксном варианте.

Если постфиксная форма инкремента реализуется как функция, которая не является функцией-членом класса, то, когда компилятор встречает выражение c0++, он генерирует вызов функции operator++(c0, 0). Прототип такой функции должен быть объявлен в классе С как дружественный:

friend C& operator++(C&, int);

Опять формальный аргумент 0 используется компилятором только для того, чтобы список аргументов функции operator++, которая используется для постфиксной формы инкремента, отличался от списка аргументов функции operator++, используемой для префиксной формы инкремента.

Все рассмотренное в этом разделе по отношению к перегрузке операций инкремента в префиксной и постфиксной формах, применимо и к перегрузке операций декремента.

Следующая программа иллюстрирует возможности применения разных операций-функций для постфиксной и префиксной операций ++ и --.

#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

<< "\tx = " << x << endl;

}

pair& operator --()

{

cout << "prefix --" << endl;

N /= 10; x /= 10;

return *this;

}

pair& operator --(int k)

{

cout << "postfix --" << endl;

N/=2; x /= 2.0;

return *this;

}

};

pair& operator ++(pair& P)

{

cout << "prefix ++" << endl;

P.N *= 10;

P.x *= 10;

return P;

}

pair& operator ++(pair& P, int k)

{

cout << "postfix ++" << endl;

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();

}

Для демонстрации полной независимости смысла перегруженной операции от ее традиционного (стандартного) значения в операциях-функциях для префиксных операций ++ соответствуют увеличению в 10 раз, а -- - уменьшению в 10 раз. Для постфиксных операций ++ определено как увеличение в 2 раза, а -- как уменьшение в 2 раза. Попытки использовать в постфиксных операциях-функциях значение дополнительного параметра int kподтверждает его равенство 0.

Результаты выполнения программы:

Координаты: N =10 x = 20

prefix ++

Координаты: N = 100 x = 200

prefix --

Координаты: N = 10 x = 20

postfix ++

Координаты: N = 20 x = 40

postfix --

Координаты: N = 10 x = 20

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]