C++. Overloading of operator () of function call. Examples

Overloading of operator () of function call. Examples


Contents


1. Features overload operator () function call. The operator function operator()(). General form

The function call operator may be overloaded. In this case, an operator function operator()() is created in the class. This function can take an arbitrary number of parameters.

The general form of the implementation of the operator function which overloads operator operator()() is as follows. If operator()() operator function is overloaded in a certain class named ClassName

class ClassName
{
    // ...

    return_type operator()(parameters)
    {
        // ...
    }
};

then when called in another code of the object named obj of class ClassName

ClassName obj;
obj(parameters);

this call will be converted to the next call of the operator function

obj.operator()(parameters);

here

  • ClassName – the name of the class in which the operator()() operator function is implemented;
  • return_type – the type that the operator()() operator function returns;
  • parameters – parameters that operator()() operator function receives;
  • obj – instance (object) of class ClassName.

 

2. How many parameters can the operator function operator()() take which overloads the function call operator?

The operator function operator()() can receive any number of parameters. The operator function operator()() can be without parameters.



 

3. Examples of overloading of operator function ()

Example 1. A SqEqual class is specified that contains all the data and methods for solving a quadratic equation.

In class SqEqual are implemented

  • internal hidden (private) data a, b, c, x1, x2 for solving the problem;
  • class constructor;
  • internal hidden (private) function Solution(), which implements an algorithm for solving a quadratic equation. This function is called from other methods and operator functions of the class;
  • public methods GetSolution() and GetSolutionP(), which call the Solution() function to solve a quadratic equation. These methods can be called from a class instance. The methods are implemented to demonstrate the passing of parameters by reference and by pointer;
  • two overloaded public operator functions operator()() that can be called to obtain a solution to a quadratic equation. Functions receive a different number of parameters, so they are perceived by the compiler as different functions. The operator()() function with two parameters as the coefficients of the equation uses the value of the internal private variables a, b, c of the class. The operator()() function with five parameters uses input parameters a, b, c to solve.

The text of the program that contains the implementation of the SqEqual class created using the Console Application template is as follows

#include <iostream>
using namespace std;

// a class that implements data and methods for solving a quadratic equation
class SqEqual
{
private:
    // coefficients of quadratic equation
    double a;
    double b;
    double c;

    // solutions
    double x1;
    double x2;

    // internal method for solving a quadratic equation
    bool Solution(void)
    {
        double d; // discriminant

        // is there any equation?
        if (a==0)
            return false;

        d = b*b-4*a*c;

        if (d>=0)
        {
            // the equation has a solution
            x1 = (-b - sqrt(d)) / (2*a);
            x2 = (-b + sqrt(d)) / (2*a);
        }
        else
            return false; // the equation has no solution

        return true; // solution in variables x1, x2
    }

public:
    // class constructor
    SqEqual(double a, double b, double c)
    {
        this->a = a;
        this->b = b;
        this->c = c;
    }

    // public methods for solving a quadratic equation
    bool GetSolution(double& x1, double& x2)
    {
        if (Solution()) // cause internal method for solving
        {
            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;
    }

    // the operator function, which solves a quadratic equation
    // operator function receives 5 parameters
    // the function returns true if the equation has a solution,
    // x1, x2 - equation solution, the passing using the pointer
    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;
    }

    // option 2 - the operator function receives only 2 parameters, which is a solution
    // x1, x2 - passing by reference
    bool operator()(double& x1, double& x2)
    {
        // the coefficients a, b, c are obtained from the current object
        if (Solution())
        {
            x1 = this->x1;
            x2 = this->x2;
            return true; // there is a solution
        }
        return false; // the equation has no solution
    }
};

void main(void)
{
    // the overloading of operator () of function call
    double a = 2, b = -3, c = 1;
    SqEqual e(a, b, c); // create an instance
    double x1, x2;
    bool f;

    // a call to the operator function operator()() with two parameters
    f = e(x1,x2);

    if (f)
    {
        // if there is a solution to the equation 2*x^2-3*x+1=0, then display the result
        cout << a << "* x^2 + (" << b << ") * x + (" << c << ") = 0" << endl;
        cout << "x1 = " << x1 << endl;
        cout << "x2 = " << x2 << endl << endl;
    }

    // invoke the operator function with 5 parameters
    f = e(5, -7, 2, &x1, &x2);

    if (f)
    {
        // if there is a solution of the equation, then display the result
        cout << "5 * x^2 - 7*x + 2 = 0" << endl;
        cout << "x1 = " << x1 << endl;
        cout << "x2 = " << x2 << endl << endl;
    }
}

As can be seen from the above code, in the main() function, the operator()() operator function call with two parameters is the following

f = e(x1,x2);

If the equation has a solution, then the variables x1 and x2 will have corresponding values. In this operator function, the transfer of values to variables x1, x2 occurs by reference.

A call to the operator function operator()() with five parameters is as follows

f = e(5, -7, 2, &x1, &x2);

In this case, the addresses of the variables x1, x2 are passed to the function. In a function, access to variables occurs by pointer.

The result of the program

2* x^2 + (-3) * x + (1) = 0
x1 = 0.5
x2 = 1

5 * x^2 - 7*x + 2 = 0
x1 = 0.4
x2 = 1

Example 2. Let a class Point be given that implements a point on the coordinate plane.

In the class Point are declared:

  • internal private variables x, y;
  • a class constructor that initializes the variables x, y to zero;
  • access methods to internal variables SetP(), GetX(), GetY();
  • overloaded operator function operator()() without parameters. This function returns the current object (instance) of the class;
  • overloaded operator function operator()() with two parameters. This function returns the current instance of the class, the values of the internal variables x, y of which are equal to the values of the corresponding parameters _x, _y.

The implementation of the Point class is as follows:

// class that implements a point
class Point
{
private:
    int x, y;

public:
    Point()
    {
        x = y = 0;
    }

    // access methods
    void SetP(int _x, int _y)
    {
        x = _x;
        y = _y;
    }

    int GetX() { return x; }
    int GetY() { return y; }

    // overloading operator function operator()() without parameters
    Point operator()()
    {
        return *this; // return the current object
    }

    // overloading operator function operator()() with two parameters
    Point operator()(int _x, int _y)
    {
        x = _x;
        y = _y;
        return *this;
    }
};

Using the operator function operator()() of class Point in another method may be as follows

// the overloading of operator () of function call
Point p1; // create an object
int t;

p1.Set(3,5); // set a value

Point p2; // new object

// invoke the operator function without parameters
p2 = p1();

// checking
t = p2.GetX(); // t = 3
t = p2.GetY(); // t = 5

// invoke the operator function operator()() with two parameters
p2 = p1(7,8);

// checking
t = p2.GetX(); // t = 7
t = p2.GetY(); // t = 8

As can be seen from the above example, the operator function operator()() can have several implementations in a class. These implementations must differ in the number or types of parameters that are passed to the operator function.

 

4. An example of using the operator function operator()() which is used in combination with another operator function operator+()

In the example, the Complex class is declared, in which are overloaded:

  • function call operator ();
  • summation operator +, which implements summation of complex numbers.

The Complex class implements the following elements:

  • internal private variables real and imag. These variables define the real and imaginary part of a complex number;
  • two constructors;
  • methods GetI() and GetR() for reading the values of the internal variables real and imag;
  • the operator function operator+(), which overloads the operator +. The function summarizes two instances (objects) of the class Complex;
  • operator function operator()(), which overloads the operator () of function call. The function creates an instance of the Complex class based on input parameters.

The program text of the Console Application type, demonstrating the implementation of the Complex class

#include <iostream>
using namespace std;

// class that implements a complex number
class Complex
{
private:
    double real; // real part of a complex number
    double imag; // imaginary part

public:
    // constructors
    Complex()
    {
        real = imag = 0;
    }

    Complex(double real, double imag)
    {
        this->real = real;
        this->imag = imag;
    }

    // access methods
    double GetI() { return imag; }
    double GetR() { return real; }

    // overloaded operator +
    Complex operator+(Complex c)
    {
        // summation of complex numbers
        return Complex(real + c.real, imag + c.imag);
    }

    // overloaded operator of function call
    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;

    // calling the operator functions operator+() and operator()()
    c3 = c1 + c2(5, 6); // c3 = c1.operator+(c2.operator(5,6))

    // checking
    r = c3.GetR(); // r = 3 + 5 = 8
    i = c3.GetI(); // i = 4 + 6 = 10

    cout << "r = " << r << endl;
    cout << "i = " << i;
}

The result of the program

r = 8
i = 10

 


Related topics