Перегрузка операций в языке программирования С++

№90-1,

физико-математические науки

В работе на примерах рассмотрена тема «Перегрузка унарных и бинарных операций в языке программирования С++». Примеры могут быть использованы в качестве образца студентами и школьниками при выполнении лабораторных и контрольных работ.

Похожие материалы

Тема перегрузка операций для класса пользователя в языке программирования С++ является достаточно сложной [1, 2]. Часто при выполнении лабораторных и контрольных работ студенты допускают ошибки. В связи с этим в данной работе на элементарном уровне объясняются некоторые понятия этой темы. Приведенные в работе программы для среды Borland C++ версии 5.02 предназначены для начинающего программиста.

Перегрузка операций встречается не только при выполнении студентами выпускных квалификационных работ и курсовых проектов [3, 4], а также приходится перегружать операции при решении разных прикладных математических задач [5, 6].

Язык C++ разрешает переопределять действие многих операций для пользовательских классов. При переопределении операций их можно использовать с объектами конкретного класса, т.е. собственные типы данных можно использовать точно так же, как стандартные. Обозначения для собственных операций нельзя вводить. Перегружать можно только существующие в C++ операции. Нельзя перегружать операции: разрешение области видимости, выбор элемента, указатель на элемент, условный оператор сравнения.

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

  • не должны иметь аргументов по умолчанию;
  • наследуются (кроме операции присваивания);
  • не могут устанавливаться как статические.

Функцию-операцию можно определить следующими способами:

  • с помощью метода класса;
  • с помощью дружественной функции;
  • обычной функции.

Функция-операция имеет следующий вид:

<тип> operator <операция> (<список_параметров>) { <тело_функции> }

Создавать новые операции невозможно; перегружать можно только уже существующие операции.

Операции (), [], -> и = перегружаются только с помощью метода класса.

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

Если функция определяется вне класса, она должна иметь один параметр типа класса.

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

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

Пример перегрузки унарных операций.

Задание. Описать класс дробь. Перегрузить операции постфиксного и префиксного инкремента.

#include <iostream.h>#include <conio.h>#include <stdlib.h>typedef long int li;     // определение типаclass drob{li sic,zn;     // класс имеет два поляvoid sokr();     // описание конструктора класса          public:   drob( li s,li z){ sic=s;if(z==0){cout<<"Деление на нуль"; getch(); exit(1);}zn=z;sokr();}/* перегрузка операции префиксного инкремента */drob operator++(){sic=sic+zn;return *this;}/* перегрузка операции постфиксного инкремента */drob operator++(int){drob x=*this; sic=sic+zn;return x;}     // метод для вывода дроби на экранvoid drob_print();};// определение метод для вывода дроби на экранvoid drob::drob_print(){cout<<sic<<"/"<<zn<<"\n";}/* определение метода, проводящего дробь к не сокращаемому виду */void drob::sokr(){ int i=2,n;if(abs(sic)<abs(zn))n=abs(sic);else n=abs(zn);while(i<=n/2){if(sic%i==0&&zn%i==0){sic/=i;  zn/=i;}else i++;}}int main() {// описание объекта d1 типа дробьdrob d1(3,14);cout<<"Начальное значение объекта d1=";d1.drob_print();// описание объекта d2 типа дробь и присваивание ++d1drob d2=++d1;cout<<"После d2=++d1 значение объекта d2=";// вывод на экран значения дроби d2d2.drob_print();cout<<"Значение объекта d1=";// вывод на экран значения дроби d1d1.drob_print();// описание объекта d3 типа дробь и присваивание d1++drob d3=d1++;cout<<"После d3=d1++ значение объекта d3=";// вывод на экран значения дроби d3d3.drob_print();cout<<"Значение объекта d1=";d1.drob_print();getch();return 0;}

В данном примере перегрузку операций префиксного и постфиксного инкремента можно было выполнить с помощью дружественных функций:

friend drob operator++(drob &t) { t.sic=t.sic+t.zn;return t;}friend drob operator++(drob &t,int) {drob x=t; t.sic=t.sic+t.zn; return x;}

Перегрузка бинарных операций.

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

Пример перегрузки бинарных операций.

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

#include <iostream.h>#include <conio.h>#include <stdlib.h>typedef long int li;class drob{ li sic,zn;void sokr();public:drob( li s,li z);drob operator+(const drob &x);  //drob + drob     void drob_print();};drob::drob( li s,li z){ sic=s;if(z==0){cout<<"Деление на нуль"; getch(); exit(1);}zn=z;sokr();}/* определение функции-операции перегрузки бинарной операции сложения двух дробей */drob drob::operator+(const drob &x) {drob temp(0,1);temp.sic=sic*x.zn+x.sic*zn;     temp.zn=zn*x.zn;temp.sokr();     return temp;}void drob::drob_print(){cout<<sic<<"/"<<zn<<"\n";}void drob::sokr(){ int i=2,n;if(abs(sic)<abs(zn))n=abs(sic);else n=abs(zn);while(i<=n/2){if(sic%i==0&&zn%i==0){sic/=i;  zn/=i;}else i++;}}int main() {// описание двух объектов типа дробьdrob d1(1,2),d2(1,3);cout<<"Значение объекта d1=";d1.drob_print();cout<<"Значение объекта d2=";     d2.drob_print();     drob d3=d1+d2;cout<<"После сложения дробей d1 и d2 получим значение: ";d3.drob_print();getch();return 0;}

Временный объект temp используется внутри функции operator+() для хранения результата и является возвращаемым объектом. После вызова операции сложения значения у операндов не изменяются, результат сложения присваивается объекту temp. Функция-операция возвращает значение temp.

Смысл того, что функция operator+() возвращает объект типа drob, состоит в том, что это позволяет использовать результат сложения объектов типа drob в сложном выражении. Например, d3 = d1 + d2; или d4 = d1 + d2 + d3;

Заключение

Таким образом, в работе рассмотрена тема «Перегрузка унарных и бинарных операций в языке программирования С++». Приведенный пример может быть использован в качестве образца студентами и школьниками при выполнении лабораторных и контрольных работ.

Список литературы

  1. Дубров Г.В. Основы программирования на С++. – М.: Конкорд, 1993. – 219 c.
  2. Подбельский В.В. Язык С++: Учебное пособие – 5 изд. – М: Финансы и статистика, 2004. – 560 c.
  3. Шилдт Г. С++: базовый курс. 3-е издание. – М.: Издательский дом "Вильямс". 2010. – 624 с.
  4. Хусаинова Г.Я. Этапы проектирования информационной системы // Вестник Технологического университета. 2018. Т. 21. № 6. – С. 153-156.
  5. Хусаинова Г.Я., Хусаинов И.Г. Разработка информационной системы "Водные ресурсы республики Башкортостан" // Современные наукоемкие технологии. 2018. № 9. С. 141-144.
  6. Хусаинов И.Г. Тепловые процессы при акустическом воздействии на насыщенную жидкостью пористую среду // Вестник Башкирского университета. 2013. Т. 18. № 2. С. 350-353.