Перегрузка оператора ()
Перегрузка функций обеспечивает механизм создания и выполнения вызовов функций с одним и тем же именем, но с разными параметрами. Это позволяет одной функции работать с несколькими разными типами данных (без необходимости придумывать уникальные имена для каждой из функций).
int subtract(int a, int b){
return a - b;
}
double subtract(double a, double b){
return a - b;
}В языке C++ операторы реализованы в виде функций. Используя перегрузку функции оператора, вы можете определить свои собственные версии операторов, которые будут работать с разными типами данных (включая пользовательские типы). Это называется перегрузкой оператора.
Перегрузка операторов позволяет нам определить самим тип параметров, при этом количество аргументов должно быть фиксировано. Например, оператор == всегда принимает два параметра (бинарный оператор), тогда как оператор ! всегда принимает один параметр (унарный оператор). Оператор () является особенно интересным, поскольку позволяет изменять как тип параметров, так и их количество.
Но следует помнить о двух вещах:
- Перегрузка круглых скобок должна осуществляться через метод класса.
- Оператор
()является оператором вызова функции. В случае с классами перегрузка круглых скобок выполняется в методеoperator()(){}(в объявлении функции перегрузки находятся две пары круглых скобок).
Перегрузка оператора () используется в реализации функторов (или «функциональных объектов») — классов, которые работают как функции. Преимущество функтора над обычной функцией заключается в том, что функторы могут хранить данные в переменных-членах (поскольку они сами являются классами). Вот пример использования простого функтора:
class Accumulator{
private:
int mcounter = 0;
public:
Accumulator() { }
int operator() (int i) {
return (mcounter += i);
}
};
int main(){
Accumulator accum;
cout << accum(30) << endl; // выведется 30
cout << accum(40) << endl; // выведется 70
}Использование класса Accumulator выглядит так же, как и вызов обычной функции, но наш объект класса Accumulator может хранить значение, которое увеличивается.
Конечно, можно было просто создать функцию и использовать в ней статическую локальную переменную. Однако, поскольку функции представлены только одним глобальным экземпляром (т.е. нельзя создать несколько объектов функции), использовать эту функцию мы можем только для выполнения чего-то одного за раз. С помощью функторов мы можем создать любое количество отдельных функциональных объектов, которые нам нужны, и использовать их одновременно.