C++ Перегрузка операторов и перегрузка функций

C++ позволяет в одной и той же области видимости некоторой [функции]ФункцияиОператорыУказывать несколько определений, соответственно называемыхПерегрузка функцийиПерегрузка операторов。

Объявление перегрузки — это объявление, которое имеет то же имя, что и функция или метод, объявленные ранее в этой области видимости, но их списки параметров и определения (реализации) различаются.

Когда вы вызываетеперегруженную функциюилиперегруженный операторкомпилятор решает, какое определение наиболее подходит, сравнивая используемые вами типы параметров с типами параметров в определении. Процесс выбора наиболее подходящей перегруженной функции или перегруженного оператора называетсяРазрешение перегрузки。

Перегрузка функций в C++

В одной и той же области видимости можно объявить несколько функций со схожей функциональностью и одинаковым именем, но эти одноимённые функции должны иметь разные формальные параметры (имеется в виду количество, тип или порядок параметров). Нельзя перегружать функции, основываясь только на разных возвращаемых типах.

В следующем примере функции с одинаковым именемprint()используются для вывода различных типов данных:

Пример

#include <iostream> using namespace std; class printData { public: void print(int i) { cout << "Целое число:" << i << endl; } void print(double f) { cout << "Число с плавающей запятой:" << f << endl; } void print(char c[]) { cout << "Строка:" << c << endl; } }; int main(void) { printData pd; // Вывод целого числа pd.print(5); // Вывод числа с плавающей запятой pd.print(500.263); // Вывод строки char c[] = "Hello C++"; pd.print(c); return 0; }

Когда приведенный выше код скомпилирован и выполнен, он выдает следующие результаты:

整数为: 5
浮点数为: 500.263
字符串为: Hello C++

Перегрузка операторов в C++

Вы можете переопределить или перегрузить большинство встроенных операторов C++. Таким образом, вы можете использовать операторы с пользовательскими типами.

Перегруженные операторы — это функции с особыми именами. Имя функции состоит из ключевого слова `operator`, за которым следует символ перегружаемого оператора. Как и другие функции, перегруженный оператор имеет возвращаемый тип и список параметров.

Box operator+(const Box&);

Объявите оператор сложения, чтобы складывать два объекта Box и возвращать итоговый объект Box. Большинство перегруженных операторов можно определить как обычные функции, не являющиеся членами класса, или как функции-члены класса. Если мы определим приведённую выше функцию как функцию, не являющуюся членом класса, то для каждой операции нужно будет передавать два параметра, как показано ниже:

Box operator+(const Box&, const Box&);

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

Пример

#include <iostream> using namespace std; class Box { public: double getVolume(void) { return length * breadth * height; } void setLength( double len ) { length = len; } void setBreadth( double bre ) { breadth = bre; } void setHeight( double hei ) { height = hei; } // Перегрузка оператора + для сложения двух объектов Box Box operator+(const Box& b) { Box box; box.length = this->length + b.length; box.breadth = this->breadth + b.breadth; box.height = this->height + b.height; return box; } private: double length; // Длина double breadth; // Ширина double height; // Высота }; // Главная функция программы int main( ) { Box Box1; // Объявить Box1 типа Box Box Box2; // Объявить Box2 типа Box Box Box3; // Объявить Box3 типа Box double volume = 0.0; // Сохранить объем в этой переменной // Детали Box1 Box1.setLength(6.0); Box1.setBreadth(7.0); Box1.setHeight(5.0); // Детали Box2 Box2.setLength(12.0); Box2.setBreadth(13.0); Box2.setHeight(10.0); // Объем Box1 volume = Box1.getVolume(); cout << "Объем Box1 : " << volume <<endl; // Объем Box2 volume = Box2.getVolume(); cout << "Объем Box2 : " << volume <<endl; // Сложить два объекта, чтобы получить Box3 Box3 = Box1 + Box2; // Объем Box3 volume = Box3.getVolume(); cout << "Объем Box3 : " << volume <<endl; return 0; }

Когда приведенный выше код скомпилирован и выполнен, он выдает следующие результаты:

Volume of Box1 : 210
Volume of Box2 : 1560
Volume of Box3 : 5400

Перегружаемые операторы / Неперегружаемые операторы

Ниже приведён список операторов, которые можно перегружать:

Бинарные арифметические операторы + (сложение), - (вычитание), * (умножение), / (деление), % (остаток от деления)
Операторы отношения == (равно), != (не равно), < (меньше), > (больше), <= (меньше или равно), >= (больше или равно)
Логические операторы || (логическое ИЛИ), && (логическое И), ! (логическое НЕ)
Унарный оператор + (положительный), - (отрицательный), * (разыменование), & (взятие адреса)
Операторы инкремента и декремента ++ (инкремент), -- (декремент)
Побитовые операторы | (побитовое ИЛИ), & (побитовое И), ~ (побитовое НЕ), ^ (побитовое исключающее ИЛИ), << (сдвиг влево), >> (сдвиг вправо)
Операторы присваивания =, +=, -=, *=, /= , % = , &=, |=, ^=, <<=, >>=
Выделение и освобождение памяти new, delete, new[ ] , delete[]
Другие операторы ()(вызов функции),->(доступ к члену),,(запятая),[](индексация)

Ниже приведён список операторов, которые нельзя перегружать:

  • .Оператор доступа к члену
  • .*, ->*Оператор доступа к указателю на член
  • ::: оператор разрешения области видимости
  • sizeof: оператор длины
  • ?:: условный оператор
  • #: символ препроцессинга

Пример перегрузки операторов

Ниже приведены различные примеры перегрузки операторов, которые помогут вам лучше понять концепцию перегрузки.

Порядковый номерОператоры и примеры
1Перегрузка унарных операторов
2Перегрузка бинарных операторов
3Перегрузка операторов отношения
4Перегрузка операторов ввода/вывода
5Перегрузка операторов ++ и --
6Перегрузка оператора присваивания
7Перегрузка оператора вызова функции ()
8Перегрузка оператора индекса []
9Перегрузка оператора доступа к членам класса ->
Другие расширения