Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабораторная работа №4,№5.pdf
Скачиваний:
105
Добавлен:
11.02.2015
Размер:
1.13 Mб
Скачать

Основы создания программ в Си

Page 35 of 58

тип operator@(список параметров):

где @ — символ операции. Слово operator является зарезервированным словом и может использоваться только в определении или в функциональной форме вызова операции.

Перегрузка операций внешними функциями

Прототип бинарной операции, перегружаемой как внешняя независимая функция, выглядит так:

тип operator@(параметр1, параметр2);

Для обеспечения коммутативности бинарной операции с параметрами разного типа, как правило, требуется реализовать две функции-операции:

тип operator@(параметр1, параметр2);

тип operator@(параметр2, параметр1);

Хотя бы один из параметров должен быть нового типа. Параметры можно передавать любым допустимым способом. Обращение к операции выполняется двумя способами:

инфиксная форма параметр1 @ параметр2;

функциональная форма operator@(параметр1, параметр2);

Прототип унарной операции, перегружаемой независимой внешней функцией, отличается только количеством параметров:

тип operator@(параметр);

Параметр должен быть нового типа. Обращаться к перегруженной операции следует так:

инфиксная форма @параметр;

функциональная форма operator@(параметр).

Операции инкремента ++ и декремента - • имеют две формы: префиксную и постфиксную. В определении постфиксной формы операции должен быть объявлен дополнительный параметр типа int.

тип operator@(параметр, int);

Этот параметр не должен использоваться в теле функции. Инфиксная форма обращения к такой операции — параметр@; при функциональной форме обращения необходимо задавать второй фиктивный аргумент, например

operator@( параметр, 0);

В примере 5.1 приведен пример перегрузки операций для перечислимого типа.

Пример 5.1: Перегрузка операций для перечислимого типа

Основы создания программ в Си

Page 36 of 58

 

 

 

#include "stdafx.h" using namespace std; // перечислимый тип enum Week { mon = 1, Week operator+(const

{

tue, wed, thu, fri, sat, sun = 0 }; Week &m, const int &b)

Week t = Week(b + m); return (t = Week(t%7));

}

// вторая функция для коммутативности сложения

Week operator+(const int &b, const Week &m)

{

return (m+b);

}

Week operator++ (Week &m) // префиксная форма

{

return (m = Week(m+1));

}

Week operator++(Week &m, int) // постфиксная форма

{

Week t = m;

m = Week(m+1); return t;

}

void print(const Week &d) // вывод на экран названий дней недели

{

std::string Days[7] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",

"Friday", "Saturday"};

cout << &Days[d]; cout << "\n";

}

int _tmain(int argc, _TCHAR* argv[])

{

 

Week m = sat;

// m - суббота

print(m+1);

// выводит 'Sunday'

print(2+m);

// выводит 'Monday'

print(operator+(m,1));

// выводит 'Sunday'

print(operator+(2,m));

// выводит 'Monday'

m++;

// вызов постфиксной формы, m — sun

Основы создания программ в Си

Page 37 of 58

 

 

 

 

 

print(m);

// выводит 'Sunday'

 

 

print(++m);

// выводит 'Monday'

 

 

print(operator++(m));

// префиксная форма, выводит 'Tuesday'

 

 

print(operator++(m,0));

// постфиксная форма, выводит 'Tuesday'

 

 

print(m);

// выводит 'Wednesday'

 

 

return 0;

 

 

 

 

}

 

 

 

 

 

 

 

 

При перегрузке операции внешней для класса функцией поля должны быть открыты или класс должен предоставлять методы get() и set() для получения и изменения значений полей.

Пример перегрузки операции внешней функцией для класса показан в примере 5.2.

Пример 5.2 Перегрузка операции сложения для класса независимой функцией

struct Fraction

 

{

 

int num;

 

int denum;

// поля - открыты

void reduce();

// иетод - открыт

};

 

void Fraction::reduce()

{

}

Fraction operator+(const Fraction &l, const Fraction &r)

{

Fraction t;

 

// (a.b)+(c.d)=(ad+bc.bd)

 

t.denum = l.denum*r.denum;

// знаменатель результата

t.num = l.num*r.denum+r.num*l.denum;

// числитель результата

t.reduce();

// сокращение

return t;

 

}

int _tmain(int argc, _TCHAR* argv[])

{

Fraction a, b, c;

 

// ...

 

a = b + c;

// инфиксная форма

a = operator+(b,c);

// функциональная форма

return 0;

 

Основы создания программ в Си

Page 38 of 58

 

 

 

}

Перегрузка операций методами класса

У методов один параметр — текущий объект — определен по умолчанию. Унарные операции выполняются для текущего объекта, который и является единственным аргументом. Поэтому унарные операции, перегружаемые как методы класса, не имеют параметров. Прототип унарной операции, реализованной как метод класса, выглядит так:

тип operator@();

где @ — символ операции. Возвращаемое значение может быть любого типа, в том числе и определяемого класса Операция может возвращать значение, ссылку или указатель на объект. Разрешается указывать void на месте типа возвращаемого значения.

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

Префиксная форма инкремента (и декремента) должна иметь прототип

тип& operator@();

Постфиксная операция инкремента (и декремента) должна иметь прототип

тип operator@(int);

Тип — это «имя_класса», в котором определяется операция.

Прототип бинарной операции имеет один аргумент и выглядит таким образом:

тип operator@(параметр);

Параметры разрешается передавать любым удобным нам способом: по значению, по ссылке или по указателю. Возвращать метод-операция тоже может значение» указатель или ссылку на объект, в том числе и своего класса. Разрешается указывать void на месте типа возвращаемого значения.

При реализации метода-операции вне класса требуется в заголовке обычным образом указывать префикс-имя класса:

тип класс::operator@()

// унарная операция

тип класс::орегатор@(параметр)

// бинарная операция

Вызов унарной операции для объекта имеет форму

@объект

объект@