Механизм, в котором мы можем использовать оператор с пользовательским типом данных. Это одна из многих интересных особенностей языка C++. Это полиморфизм времени компиляции, который пытается заставить пользовательские типы данных вести себя почти так же, как встроенные типы. По сути, это дает нам преимущество выполнять разные операции с одним и тем же операндом.
Например, мы можем перегрузить оператор + в таком классе, как String, чтобы мы могли объединить две строки, просто используя +.
Почти все операторы могут быть перегружены, кроме нескольких. Ниже приведен список операторов, которые нельзя перегружать:
- Оператор разрешения области видимости (::)
- Оператор размера (Sizeof)
- Тернарный оператор (?:)
- селектор элементов (.)
- селектор указателя члена (*)
Определение перегрузки оператора
Общий вид операторной функции:
имя класса returnType :: оператор op(arglist)
{
Тело функции // задача определена
}
где,
- returnType – это тип значения, возвращаемого указанной операцией.
- operator op — это имя функции, где operator — ключевое слово.
- arglist — это список аргументов (аргументы, переданные функции).
Перегрузка оператора выполняется с помощью специальной функции, называемой Функция оператора, которая описывает специальную задачу для оператора.
Примечание. Разница между функцией оператора и обычной функцией.
Обычные функции и операторные функции одинаковы. Основное отличие состоит в том, что имя операторной функции всегда представляет собой ключевое слово оператора, за которым следует символ оператора, и оно вызывается при использовании соответствующего оператора.
ПРАВИЛА ПЕРЕГРУЗКИ ОПЕРАТОРА
- Только существующие операторы могут быть перегружены. Новые операторы не могут быть созданы.
- Перегруженный оператор должен иметь по крайней мере один операнд определенного пользователем типа.
- Перегруженный оператор должен следовать правилам синтаксиса исходных операторов, их нельзя переопределить.
- Функцию friend нельзя использовать для перегрузки определенных операторов (= , () , [] , -›).
- Унарные операторы, перегруженные функцией-членом, не принимают явных аргументов и не возвращают явных значений, но те, которые перегружены дружественной функцией, принимают один аргумент (объект соответствующего класса).
- При использовании бинарных операторов, перегруженных через функцию-член, левый операнд должен быть объектом соответствующего класса.
- Бинарные операторы, перегруженные функцией-членом, принимают один явный аргумент, а те, которые перегружаются дружественной функцией, принимают два явных аргумента.
Пример перегрузки оператора:
Пример перегрузки оператора в унарных операторах:
// Унарные операторы работают только с одним операндом.
// перегружаем унарный оператор декремента - -.
#include‹iostream›
использование пространства имен std;
длина класса {
плавающее значение;
струнная единица;
публичный:
длина () {} // конструктор 1
длина (значение с плавающей запятой, единица измерения строки){ // конструктор 2
это-›значение = значение;
это-›единица = единица;
}
оператор длины — (int){//функция декремента перегружена, это уменьшит значение на 1
это-›значение -= 1;
вернуть *это;
}
void display(){ // эта функция покажет значение и единицу измерения
printf(“%.2f “, это-›значение);
cout‹‹эта-›единица‹‹endl;
}
};
интервал основной () {
длина высота; // вызывает конструктор
высота = длина (5,5, «футы»);
cout‹‹” перед уменьшением высоты = “;
высота.дисплей();
высота - ;
cout‹‹”после уменьшения высоты = “;
высота.дисплей();
вернуть 0;
}
Вывод:
до уменьшения высоты = 5,50 футов
после уменьшения высоты = 4,50 футов
Примечание:
Операторы инкремента и декремента могут использоваться как до инкремента/декремента, так и после инкремента/декремента.
Реализация предварительного увеличения/уменьшения:
Класс возвращаемого значения :: opration op(){}
Реализация увеличения/уменьшения записи:
Класс возвращаемого типа :: операция op(int){}
Пример перегрузки бинарных операторов:
// работа с двумя операндами.
#include ‹iostream›
использование пространства имен std;
класс Комплекс {
плавать х, у; // действительная часть, мнимая часть
публичный:
Complex(){ } // конструктор 1
Complex(float real,float imag) // конструктор 2
{
х=реальный; у=изображение;
}
Сложный оператор+(Комплексный);
недействительный дисплей (недействительный);
};
Комплекс Комплекс :: оператор+(Комплекс c){
Комплекс т; // временный
т.х=х+с.х; // плавающие дополнения
t.y=y+c.y;
возврат (т);
}
комплекс пустоты :: display (void) {
cout‹‹ x ‹‹ «+ i» ‹‹ y ‹‹endl;
}
основной ()
{
Комплекс с1,с2,с3;
c1 = Сложный (1.4, 2.3); // вызывает конструктор 2
c2=Сложный(3,4.2); // вызывает конструктор 2
c3=c1+c2;
cout‹‹ "c1 = ";
c1.дисплей();
cout‹‹ "c2 = ";
c2.дисплей();
cout‹‹ "c3 = ";
c3.дисплей(); // результат
вернуть 0;
}
Выход:
c1 = 1,4 + i 2,3
c2 = 3 + i 4,2
c3 = 4,4 + i 6,5
Пример перегрузки оператора указателя на член (-›):
// Этот оператор обычно используется в сочетании с указателем объекта для доступа к любому члену объекта.
#include ‹iostream›
использование пространства имен std;
номер класса {
публичный:
инт н;
число (целое я) {
n=i;
}
оператор num* -›(void)
{
вернуть это; // возвращает указатель на себя
}
};
интервал основной () {
номер N(3);
номер *Ptr=
cout‹‹”N.n = “‹‹N.n‹‹endl; // Обычный доступ к n
cout‹‹”Ptr-›n = “‹‹Ptr-›n‹‹endl;//Доступ к n с использованием обычного указателя объекта
cout‹‹”N-›n = “‹‹N.n; //Доступ к n с помощью перегруженного оператора -›
вернуть 0;
}
Вывод:
N.n = 3
Ptr-›n = 3
N-›n = 3
Вышеприведенная программа демонстрирует как нормальное (Ptr-›n), так и перегруженное (N-›n) поведение оператора-›.