Перегрузка оператора ( ) вызова функции. Примеры
Содержание
- 1. Особенности перегрузки оператора ( ) вызова функции. Операторная функция operator()(). Общая форма
- 2. Сколько параметров может принимать операторная функция operator()(), которая перегружает оператор вызова функции?
- 3. Примеры перегрузки оператора ( ) вызова функции
- 4. Пример использования операторной функции operator()() которая используется в сочетании с другой операторной функцией operator+()
- Связанные темы
Поиск на других ресурсах:
1. Особенности перегрузки оператора () вызова функции. Операторная функция operator()(). Общая форма
Оператор вызова функции может быть перегружен. В этом случае, в классе создается операторная функция operator()(). Эта функция может принимать произвольное количество параметров.
Общая форма реализации операторной функции перегружающей оператор operator()() следующая.
Если в некотором классе с именем ClassName перегружена операторная функция operator()()
class ClassName { // ... return_type operator()(parameters) { // ... } };
то при вызове в другом коде объекта с именем obj класса ClassName
ClassName obj; obj(parameters);
этот вызов будет преобразован в следующий вызов операторной функции
obj.operator()(parameters);
здесь
- ClassName – имя класса, в котором реализована операторная функция operator()();
- return_type – тип, который возвращает операторная функция operator()();
- parameters – параметры, которые получает операторная функция operator()();
- obj – экземпляр (объект) класса ClassName.
⇑
2. Сколько параметров может принимать операторная функция operator()(), которая перегружает оператор вызова функции?
Операторная функция operator()() может принимать любое количество параметров. Операторная функция operator()() может быть без параметров.
⇑
3. Примеры перегрузки оператора () вызова функции
Пример 1. Задан класс SqEqual, содержащий все данные и методы для решения квадратного уравнения.
В классе SqEqual реализованы:
- внутренние скрытые (private) данные a, b, c, x1, x2 для решения задачи;
- конструктор класса;
- внутренняя скрытая (private) функция Solution(), в которой реализован алгоритм решения квадратного уравнения. Эта функция вызывается из других методов и операторных функций класса;
- общедоступные (public) методы GetSolution() и GetSolutionP(), которые вызывают функцию Solution() для решения квадратного уравнения. Эти методы можно вызывать из экземпляра класса. Методы реализованы с целью демонстрации передачи параметров по ссылке и по указателю;
- две перегруженные общедоступные (public) операторные функции operator()(), которые можно вызывать для получения решения квадратного уравнения. Функции получают разное количество параметров, поэтому они воспринимаются компилятором как разные функции. Функция operator()() с двумя параметрами в качестве коэффициентов уравнения использует значение внутренних скрытых (private) переменных a, b, c класса. Функция operator()() с пятью параметрами для решения использует входные параметры a, b, c.
Текст программы, которая содержит реализацию класса SqEqual, созданной по шаблону Console Application следующий
#include <iostream> using namespace std; // класс, который реализует данные и методы решения квадратного уравнения class SqEqual { private: // коэффициенты квадратного уравнения double a; double b; double c; // корни - решения double x1; double x2; // внутренний метод решения квадратного уравнения bool Solution(void) { double d; // дискриминант // есть ли вообще уравнение? if (a==0) return false; d = b*b-4*a*c; if (d>=0) { // уравнение имеет решение x1 = (-b - sqrt(d)) / (2*a); x2 = (-b + sqrt(d)) / (2*a); } else return false; // уравнение не имеет решения return true; // решение в переменных x1, x2 } public: // конструктор класса SqEqual(double a, double b, double c) { this->a = a; this->b = b; this->c = c; } // общедоступные методы решения квадратного уравнения bool GetSolution(double& x1, double& x2) { if (Solution()) // вызвать внутренний метод решения { x1 = this->x1; x2 = this->x2; return true; // есть решение } return false; // нету решения } bool GetSolutionP(double* x1, double* x2) { if (Solution()) { *x1 = this->x1; *x2 = this->x2; return true; // есть решение } return false; // нет решения } // операторная функция operator()(),решающая квадратное уравнение // операторная функция получает 5 параметров // функция возвращает true, если уравнение имеет решение, // x1, x2 - решение уравнения, передача по указателю bool operator()(double a, double b, double c, double* x1, double* x2) { this->a = a; this->b = b; this->c = c; if (Solution()) { *x1 = this->x1; *x2 = this->x2; return true; } return false; } // вариант 2 - операторная функция получает только 2 параметра, которые есть решением // x1, x2 - передача по ссылке bool operator()(double& x1, double& x2) { // коэффициенты a, b, c получаются из текущего объекта if (Solution()) { x1 = this->x1; x2 = this->x2; return true; // есть решение } return false; // уравнение не имеет решения } }; void main(void) { // перегрузка оператора () вызова функции double a = 2, b = -3, c = 1; SqEqual e(a, b, c); // создать экземпляр double x1, x2; bool f; // вызов операторной функции operator()() с двумя параметрами f = e(x1,x2); if (f) { // если есть решение уравнения 2*x2-3*x + 1 = 0, то вывести результат cout << a << "* x^2 + (" << b << ") * x + (" << c << ") = 0" << endl; cout << "x1 = " << x1 << endl; cout << "x2 = " << x2 << endl << endl; } // вызов операторной функции с 5 параметрами f = e(5, -7, 2, &x1, &x2); if (f) { // если есть решение уравнения, то вывести результат cout << "5 * x^2 - 7*x + 2 = 0" << endl; cout << "x1 = " << x1 << endl; cout << "x2 = " << x2 << endl << endl; } }
Как видно из вышеприведенного кода, в функции main() вызов операторной функции operator()() с двумя параметрами следующий
f = e(x1,x2);
Если уравнение имеет решение, то переменные x1 и x2 будут иметь соответствующие значения. В этой операторной функции передача значений в переменные x1, x2 происходит по ссылке.
Вызов операторной функции operator()() с пятью параметрами следующий
f = e(5, -7, 2, &x1, &x2);
В этом случае в функцию передаются адреса переменных x1, x2. В функции доступ к переменным происходит по указателю.
Результат выполнения программы
2* x^2 + (-3) * x + (1) = 0 x1 = 0.5 x2 = 1 5 * x^2 - 7*x + 2 = 0 x1 = 0.4 x2 = 1
Пример 2. Пусть задан класс Point, реализующий точку на координатной плоскости.
В классе Point объявляются:
- внутренние скрытые (private) переменные x, y;
- конструктор класса, который инициализирует нулевыми значениями значения переменных x, y;
- методы доступа к внутренним переменным SetP(), GetX(), GetY();
- перегруженная операторная функция operator()() без параметров. Эта функция возвращает текущий объект (экземпляр) класса;
- перегруженная операторная функция operator()() с двумя параметрами. Эта функция возвращает текущий экземпляр класса, значение внутренних переменных x, y которого равно значению соответствующих параметров _x, _y.
Реализация класса Point следующая:
// класс, реализующий точку class Point { private: int x, y; public: Point() { x = y = 0; } // методы доступа void SetP(int _x, int _y) { x = _x; y = _y; } int GetX() { return x; } int GetY() { return y; } // перегрузка операторной функции operator()() без параметров Point operator()() { return *this; // вернуть текущий объект } // перегрузка операторной функции operator()() с двумя параметрами Point operator()(int _x, int _y) { x = _x; y = _y; return *this; } };
Использование операторной функции operator()() класса Point в другом методе может быть, например, таким
// перегрузка оператора () вызова функции Point p1; // создать объект int t; p1.Set(3,5); // установить значение Point p2; // новый объект // вызов операторной функции без параметров p2 = p1(); // проверка t = p2.GetX(); // t = 3 t = p2.GetY(); // t = 5 // вызов операторной функции operator()() с двумя параметрами p2 = p1(7,8); // проверка t = p2.GetX(); // t = 7 t = p2.GetY(); // t = 8
Как видно из вышеприведенного примера, операторная функция operator()() может иметь несколько реализаций в классе. Эти реализации должны отличаться количеством или типами параметров, которые передаются в операторную функцию.
⇑
4. Пример использования операторной функции operator()() которая используется в сочетании с другой операторной функцией operator+()
В примере объявляется класс Complex, в котором перегружаются:
- оператор вызова функции ();
- оператор суммирования +, осуществляющий суммирование комплексных чисел.
В классе Complex реализованы следующие элементы:
- внутренние скрытые (private) переменные real и imag. Эти переменные определяют вещественную и мнимую часть комплексного числа;
- два конструктора;
- методы GetI() и GetR() для чтения значений внутренних переменных real и imag;
- операторная функция operator+(), которая перегружает оператор +. Функция суммирует два экземпляра (объекта) класса Complex;
- операторная функция operator()(), которая перегружает оператор вызова функции (). Функция создает экземпляр класса Complex на основе входных параметров.
Текст программы типа Console Application, демонстрирующий реализацию класса Complex следующий
#include <iostream> using namespace std; // класс, реализующий комплексное число class Complex { private: double real; // вещественная часть комплексного числа double imag; // мнимая часть public: // конструкторы Complex() { real = imag = 0; } Complex(double real, double imag) { this->real = real; this->imag = imag; } // методы доступа double GetI() { return imag; } double GetR() { return real; } // перегруженный оператор суммирования + Complex operator+(Complex c) { // суммирование комплексных чисел return Complex(real + c.real, imag + c.imag); } // перегруженный оператор вызова функции Complex operator()(double real, double imag) { this->real = real; this->imag = imag; return *this; } }; void main() { Complex c1(3, 4); Complex c2; Complex c3; double r, i; // вызов операторных функций operator+() и operator()() c3 = c1 + c2(5, 6); // c3 = c1.operator+(c2.operator(5,6)) // проверка r = c3.GetR(); // r = 3 + 5 = 8 i = c3.GetI(); // i = 4 + 6 = 10 cout << "r = " << r << endl; cout << "i = " << i; }
Результат выполнения программы
r = 8 i = 10
⇑
Связанные темы
- Перегрузка операторов в C++. Операторная функция. Ключевое слово operator. Перегрузка базовых арифметических операторов +, –, *, /. Примеры реализации встроенных операторных функций
- «Дружественные» операторные функции: отличия, реализации, особенности применения. Перегрузка операторов +, –, *, / с помощью «дружественных» операторных функций
- Перегрузка оператора индексирования элементов массива [ ]
⇑