Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь FAQ Написать работу КАТЕГОРИИ: АрхеологияБиология Генетика География Информатика История Логика Маркетинг Математика Менеджмент Механика Педагогика Религия Социология Технологии Физика Философия Финансы Химия Экология ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Перегрузка функций-операторовСодержание книги
Поиск на нашем сайте
Пример: иллюстрирует перегрузку операторов для гипотетического класса с именем Z: class Z{ public: //четыре перегруженные ф-ции-//оператора friend Z operator+(Z a, Z b); friend Z operator-(Z a, Z b); friend Z operator*(Z a, Z b); friend Z operator/(Z a, Z b); //... прочие открытые, // защищенные и закрытые члены }; В классе ZZ объявлены четыре перегруженные функции-оператора. (На практике в ZZ могут объявляться и другие открытые, защищенные и закрытые члены.) Имена функций — operator+(), operator-(), operator*0 и operator/(). Обычно нельзя использовать символы типа +, -, * или / в идентификаторах, однако для перегрузки операторов в C++ имя функции может состоять из слова operator и одного из символов, приведенных в табл. 4.1. Таблица 4.1- Список операторов, которые могут быть перегружены
Операторы +, -, * и & могут перегружаться для бинарных и для унарных выражений. Операторы., .*, :: и sizeof не могут перегружаться вообще. Операторы =, (), [] и -> следует реализовать нестатическими функциями-членами.
В гипотетическом классе Z объявляются функции для первых четырех операторов из таблицы. Каждая ф-ция имеет общий вид
friend Z operator+ (Z a, Z b);
Функция объявляется дружественной классу, что дает функции operator+() доступ к закрытым и защищенным членам этого класса. Функция возвращает объекты типа Z (но может возвращать и любой другой тип), и этот результат можно присвоить другому объекту Z. (Присваивание одного объекта другому создает несколько "скользких" моментов. Эта тема будет обсуждаться позднее в этой главе.) Более важно то, что имя функции. operator+() идентифицирует функцию как метод, с помощью которого выражения, использующие оператор сложения, могут оперировать объектами класса. Предполагается, что функция operator+() складывает два объекта способом, подходящим для класса Z.
operator+() — всего лишь имя функции. Если назовем функцию именем fun() вместо operator(), то сможем употреблять операторы следующего вида: fun(a, b); где а и b — объекты типа Z.
Заменив fun на operator+, можно вызывать функцию перегрузки оператора следующим образом: operator+(a, b); // Аналогично fun(a, b)
Нет никакой разницы между этими двумя вызовами функции, отличаются только их имена.
как перегруженный оператор, функция operator+() может вызываться в выражениях, в которых используется знак плюс. Например, следующий оператор эквивалентен предыдущему вызову функции:
а + b; // Аналогично operator+(a, b);!
Выражения а + b и operator+(a, b) выполняют одну и ту же работу и в точности генерируют один и тот же код. Есть только одна причина использовать ту или иную форму - ясность. Перегрузка операторов не привносит в C++ ничего такого, чего бы вы уже не знали. Это всего лишь позволит вам использовать объекты в выражениях, вместо того чтобы передавать их функции. Работающий пример класса, в котором используются перегруженные операторы, поможет проиллюстрировать эти концепции. В листинге 4.4 содержится класс, способный запоминать целые значения в виде строк. С помощью перегруженных операторов программа может вычислять выражения, в которых складываются и вычитаются строки в виде эквивалентных им числовых значений.
ПРИМЕР 4.4. STROPS.CPP (функции перегруженных операторов) #include <iostream.h> #include <stdlib.h> #include <string.h> #include <conio.h> class TStrOp { private: char value[12]; public: TStrOp() { value[0] = '\0'; } TStrOp(const char *s); long GetValue(void) { return atoi(value); } // дружественные функции, объявленные //в строках 12—13, перегружают операторы //сложения и вычитания для пары //объектов класса TStrOp friend long operator+(TStrOp a, TStrOp b); friend long operator-(TStrOp a, TStrOp b); }; main() { TStrOp a = "1234"; TStrOp b = "4321"; cout << "Value of a ==" <<a.GetValue(); cout << "\n Value of b == “" <<b.GetValue(); cout <<"\na + b + 6 == “"<< (a+b+6); cout << "\na - b + 10 == “"<< (a-b+10); getch(); return 0; } TStrOp::TStrOp(const char *s) { strncpy(value, s, 11); value[11] = 0; } long operator+(TStrOp a, TStrOp b) { return (atoi(a.value) + atoi(b.value)); } long operator-(TStrOp a, TStrOp b) { return (atol(a.value) - atol(b.value)); } Запуск STROPS на выполнение приведет к следующим результатам: Value of a == 1234 Value of b == 4321 a + b + 6 == 5561 a - ь + 10 == -3077 Перед тем как ознакомиться с классом и его функциями перегрузки операторов в программе, рассмотрим функцию mainO. В строках 18-19 объявляются два объекта типа TStrOp — а и b. Объекты инициализируются символьными строками и могут быть реализованы также следующим образом: TStrOp a("1234"); TStrOp b("4321"); Несмотря на то что со всей очевидностью эти объекты представляют собой строковые значения, выражения в строках 23 и 24 складывают и вычитают их непосредственным образом:
(а + Ь + 6) (а - b + 10)
Обычно вы не можете использовать строки или объекты в подобных выражениях; перегрузка операторов расширяет знания C++ о том, объекты каких типов можно складывать и вычитать. Две дружественные функции, объявленные в строках 12—13, перегружают операторы сложения и вычитания для пары объектов класса TStrOp. Объявления сходны с теми, что пояснялись ранее в гипотетическом классе ZZ. Конечно, в данном случае функция возвращает длинное целое. Обычно функции перегрузки операторов имеют тип класса (или ссылки на объект класса), объектами которого они оперируют, но это не обязательно. Функции перегрузки операторов, равно как и другие функции, могут возвращать любые типы данных. Рассмотрим реализацию перегруженных операторов в строках 35-43. Поскольку функции объявлены дружественными и не членами класса, их реализация vидентична реализации обычных функций в C++. Единственное отличие заключается в специальных именах функций — operator+ и operator-, что позволяет компилятору вычислять выражения, использующие операторы сложения и вычитания с объектами класса TStrOp. Поскольку функции операторов — друзья, они имеют доступ к закрытым и защищенным членам объектов TStrOp. Этот факт позволяет функциям преобразовывать строки-значения в параметрах а и b в целое. Это преобразование осуществляется путем обращения к стандартной функции atoi (ASCII to int), прототип которой содержится в заголовочном файле STDLIB.H. Функции просто возвращают сумму или разницу преобразованных значений.
Перегрузка операторных функций-членов Перегруженные функции могут быть членами класса, как это демонстрируется в примере 4.5. Эта программа на STROPS.CPP (листинг 4.4), однако в ней иллюстрируется перегрузка операторов функциями-членами. Листинг 4.5. STR0PS2.CPP (перегрузка операторов функциями-членами) #include <iostream.h> #include <stdlib.h> #include <string.h> #include <conio.h> class TStrOp { private: char value[12]; public: TStrOp() { value[0] = 0; } TStrOp(const char *s); long GetValue(void) { return atol(value); } long operator+(TStrOp b); long operator-(TStrOp b); }; Main() { TStrOp a = "1234"; TStrOp b = "4321"; cout << "\nValue of a == " <<a.GetValue(); cout <<"\nValue of b == " <<b.GetValue(); cout <<"\na + b + 6 == "<< (a+b+6)<<"\n"; cout <<"\na - b + 10 == " << (a-b+10)<<"\n"; getch(); return 0; } TStrOp:: TStrOp(const char *s) { strncpy(value, s, 11); value[11] = 0; } long TStrOp::operator+(TStrOp b) { return (atol(value) + atol(b.value)); } long TStrOp::operator-(TStrOp b) { return (atol(value) - atol(b.value)); } //эти функции-члены получают //указатель this, ссылающийся на //объект, для которого они были //вызваны. След-но, функциям //необходим всего лишь один //параметр, а не два, как ранее. //Для сложения двух строковых //значений operator+() суммирует //длинные целые значения, //эквивалентные выражениям // this->value и b.value. Рассмотрим перегруженные операторные функции-члены, объявленные в строках 12-13 и реализованные в строках 32-33. Поскольку эти функции — члены класса TStrOp, они уже имеют доступ к защищенным и закрытым членам класса, таким образом, не надо их указывать друзьями класса. Кроме того, эти функции-члены получают указатель this, ссылающийся на объект, для которого они были вызваны. Следовательно, функциям необходим всего лишь один параметр, а не два, как ранее. Для сложения двух строковых значений operator+() суммирует длинные целые значения, эквивалентные выражениям this->value и b.value.
Функциям-операторам и функциям-членам необходимо соответствующее число параметров. Вы не сможете объявить operator+О в строке 12 следующим образом: long operator+(TStrOp a, TStrOp b); //??? Эта строка не скомпилируется, поскольку operator+О — член класса TStrOp и как функция-член получает указатель this, ссылающийся на объект класса. С учетом указателя this и аргументов а и b всего функция имеет три параметра, а перегруженному бинарному оператору, подобному operator+О, необходимы только два. Для сложения двух объектов класса TStrOp функция operator+О суммирует *this.value и b.value (строка 37). Ей не нужен третий параметр. Функция-член operator-О также получает указатель this и, следовательно, нуждается только в одном аргументе для перегрузки бинарного оператора вычитания (строки 40-43).
|
|||||||||||||||||||||||||||||||||||||||||||||||
Последнее изменение этой страницы: 2016-08-01; просмотров: 226; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.147.51.72 (0.01 с.) |