В C++ существует возможность перегрузить не только функции, но и операции внутри класса, например, можно добиться того, чтобы операция * при работе с матрицами осуществляла умножение матриц, а при работе с комплексными числами — умножение комплексных чисел.
Для перегрузки операций внутри класса нужно написать специальную функцию — метод класса. При перегрузке операций следует помнить следующее:
- нельзя поменять приоритет операций;
- нельзя изменить тип операции (из унарной операции нельзя сделать бинарную или наоборот);
- перегруженная операция является членом класса и может использоваться только в выражениях с объектами своего класса;
- нельзя создавать новые операции;
- запрещено перегружать операции: . (доступ к членам класса), унарную операцию * (значение по адресу указателя), :: (расширение области видимости), ?: (операция if);
- допустима перегрузка следующих операций: +, —, *, /, %, =, <, >, +=, -=, *=, /=, &&, ||, ++, —, (), [], new, delete.
Для перегрузки бинарной операции внутри класса необходимо создать функцию-метод:
1
2 3 4 |
type operator symbols(type1 parametr)
{ операторы; } |
Здесь type — тип возвращаемого операцией значения, operator — служебное слово, symbols — перегруженная операция, type1 — тип второго операнда, первым операндом является экземпляр текущего класса, parametr — имя переменной второго операнда.
В качестве примера рассмотрим класс complex с перегруженными операциями + (сложение комплексных чисел) и — (вычитание комплексных чисел).
Задача
Создать класс для работы с комплексными числами, в котором перегрузить операции сложения и вычитания. Текст программы с комментариями приведен ниже.
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
#include «stdafx.h»
#include <iostream> using namespace std; //класс комплексное число complex class complex { public: //конструктор класса complex(bool pr=true); //метод, реализующий перегрузку операции сложения complex operator +(complex M); //метод, реализующий перегрузку операции вычитания complex operator —(complex M); //действительная часть комплексного числа float x; //мнимая часть комплексного числа float y; //метод вывода комплексного числа на экран void show_complex(); }; //главная функция int main() { setlocale(LC_ALL,«Rus»); complex chislo, chislo1, chislo2, chislo3(false), chislo4(false); //для сложения двух комплексных чисел достаточно использовать //операцию +. В классе complex операция + перегружена для //выполнения сложения комплексных чисел chislo3=chislo1+chislo2; cout<<«chislo3 «; chislo3.show_complex(); //для вычитания двух комплексных чисел достаточно использовать //операцию -. В классе complex операция — перегружена для //выполнения вычитание комплексных чисел chislo4=chislo1—chislo2; cout<<«chislo4 «; chislo4.show_complex(); system(«pause»); return 1; } //конструктор класса complex с логическим параметром (true — //по умолчанию). Если параметр равен true, то в конструкторе //будут запрашиваться мнимая и действительная части числа, //если же параметр конструктора равен 0, то будет создаваться //комплексное число с нулевыми действительной и мнимой частями, //Такие числа можно использовать для создания переменных, в //которых будет храниться результат действий с комплексными числами complex::complex(bool pr) { if (pr) { cout<<«введите x \t«; cin>>x; cout<<«введите y \t«; cin>>y; show_complex(); } else {x=0; y=0;} } //метод вывода комплексного числа на экран void complex::show_complex() { if (y>=0) cout<<x<<«+»<<y<<«i»<<endl; else cout<<x<<y<<«i»<<endl; } //метод, реализующий перегрузку операции сложения. //Результатом этой функции будет новое комплексное число complex complex::operator+(complex M) { //создаем комплексное число temp, в котором будет храниться //результат сложения двух комплек. чисел complex temp(false); //действительная часть нового комплексного числа формируется //как результат сложения действительных частей первого и //второго операнда, первым является текущий класс, вторым — //передаваемое в функцию комплексное число M temp.x=x+M.x; //мнимая часть нового комплексного числа формируется как //результат сложения мнимых частей первого и второго операнда temp.y=y+M.y; //возвращаем сумму двух комплексных чисел в качестве результата return temp; } //метод, реализующий перегрузку операции вычитания complex complex::operator—(complex M) { complex temp(false); //действительная часть нового комплексного числа формируется //как результат вычитания действительных частей первого и //второго операнда, первым является текущий класс, вторым — //передаваемое в функцию комплексное число M temp.x=x—M.x; //мнимая часть нового комплексного числа формируется как //результат вычитания мнимых частей первого и второго операнда temp.y=y—M.y; //возвращаем разность двух комплексных чисел return temp; }; |
Для перегрузки унарной операции внутри класса необходимо создать функцию-метод:
1
2 3 4 |
type operator symbols()
{ операторы; } |
Как Вы помните, в C++ унарные операции ++ и —. Действие этих операций различается при расположении с лева и справа от операнда. Рассмотрим, как реализуется перегрузка операции ++x и x++ на примере класса комплексных чисел. Пусть операция ++x увеличивает действительную и мнимую части комплексного числа x на 1, а x++ увеличивает на 1 только действительную часть комплексного числа x.
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
#include «stdafx.h»
#include <iostream> using namespace std; class complex { public: complex(bool pr=true) { if (pr) { cout<<«введите x \t«; cin>>x; cout<<«введите y \t«; cin>>y; show_complex(); }; //функция, перегружающая оператор ++x, в этом случае //этот метод без параметров complex operator++() { //увеличиваем действительную и мнимую части на 1 x++; y++; //возвращаем текущий класс в качестве результата функции return *this; } //функция, перегружающая оператор x++, в этом случае это //метод с абстрактным параметром целого типа. Наличие //целого типа в скобках говорит только о том, что //перегружается оператор x++, а не ++x complex operator++(int) { //увеличиваем действительную и мнимую части на 1 x++; return *this; } //метод вывода комплексного числа на экран void show_complex() { if (y>=0) cout<<x<<«+»<<y<<«i»<<endl; else cout<<x<<y<<«i»<<endl; }; float x; float y; }; int main() { setlocale(LC_ALL,«Rus»); //комплексное число chislo2 complex chislo2; //увеличиваем его на 1, вызывая метод complex operator++() ++chislo2; //вывод комплексного числа cout<<«++chislo2 = «; chislo2.show_complex(); //увеличиваем его на 1, вызывая метод complex operator++(int) chislo2++; //вывод комплексного числа cout<<«chislo2++ = «; chislo2.show_complex(); system(«pause»); return 1; } |
Как видно операторы ++x и x++ были перегружены по-разному. Вы можете сами дописать в класс complex методы, реализующие перегрузку операций умножения и деления комплексных чисел.