Detailed resolution of operator overloading in C++

  • 2020-04-02 01:38:49
  • OfStack


What is operator overloading
Operator overloading can be divided into two parts: operator and overloading. This is a type of compile-time polymorphism, and overloading can actually be divided into function overloading and operator overloading. The difference between operator overloading and function overloading is that the operator overloading must be the operator. Let's start with an intuitive look at the so-called operator overloading:


#include <iostream>
using namespace std;
int main()
{
    int a = 2 , b = 3;
    float c = 2.1f , d = 1.2f;
    cout<<"a + b = "<<a+b<<endl;
    cout<<"c + d = "<<c+d<<endl;
    return 0;
}

We see that the operator "+" does the addition of float and int, which is operator overloading. These built-in types of operator overloading have already been implemented, but what if we now write our own classes that implement similar addition operations? So, for example, now that we have a point class point, and we want to add two points, and the result is that we add the horizontal and the vertical, we need to write an operator overload function.

#include <iostream>
using namespace std;
class point
{    
    double x;
    double y;
public:
    double get_x()
    {
        return x;
    }
    double get_y()
    {
        return y;
    }
    point(double X = 0.0 , double Y = 0.0):x(X),y(Y){};
    point operator +(point p);
};
//Overloading operator "+"
point point::operator +(point p)
{
    double x = this->x + p.x;
    double y = this->y + p.y;
    point tmp_p(x,y);
    return tmp_p;
}
int main()
{
    point p1(1.2,3.1);
    point p2(1.1,3.2);
    point p3 = p1+p2;
    cout<<p3.get_x()<<" "<<p3.get_y()<<endl;
    return 0;
}

Two ways to implement operator overloading
Operator overloading can be implemented in two ways, through "friend functions" or "class member functions."

1. Format of overloaded operator of friend function:


class  The name of the class 
{
    friend  The return type  operator  The operator ( Parameter table );
};
//Out-of-class definition format:
 The return type  operator The operator ( Parameter table )
{
    //The body of the function
}

2. The format of operator overload for class member functions:

class  The name of the class 
{
public:
     The return type  operator  The operator ( Parameter table ) ; 
};
//Define the format outside the class
 The return type   The name of the class ::operator  The operator ( Parameter table )
{
    //The body of the function
}

To put it this way, it is not enough to compare the two implementations. We write the "+" and "-" overloads of the point class in two implementations. The code is as follows:

#include <iostream>
using std::endl;
using std::cout;
class point
{    
    double x;
    double y;
public:
    double get_x()
    {
        return x;
    }
    double get_y()
    {
        return y;
    }
    point(double X = 0.0 , double Y = 0.0):x(X),y(Y){};
    friend point operator -(point p1,point p2);
    point operator +(point p);
};
//Overloading operator "-"
point operator -(point p1,point p2)
{
    double x = p1.get_x() - p2.get_x();
    double y = p1.get_y() - p2.get_y();
    point p3(x,y);
    return p3;
}
//Overloading operator "+"
point point::operator +(point p)
{
    double x = this->x + p.x;
    double y = this->y + p.y;
    point tmp_p(x,y);
    return tmp_p;
}
int main()
{
    point p1(1.2,3.2);
    point p2(1.1,3.1);
    point p3 = p1+p2;
    point p4 = operator-(p1,p2);
    cout<<p3.get_x()<<" "<<p3.get_y()<<endl;
    cout<<p4.get_x()<<" "<<p4.get_y()<<endl;
    return 0;
}

I don't know if you've seen this, but when you overload the binary operator "-" with a friend function, you have two formal arguments, whereas with a class member function, you only have one formal argument. At this time, because this pointer exists in the class member function, which is equivalent to an argument, so the class member implementation operator overload requires one less formal argument than the original, such as: using the class member function to implement the unary operator "-", no argument is needed. For this reason, the operator overloading of friend functions is limited, such as: [], (), - > And = cannot be overloaded by using friend functions.

In practice, the monocular operator is recommended to be overridden as a member function, while the binocular operator is recommended to be overridden as a friend function. It is often more convenient to overload the binocular operator as a friend function than as a member function, but sometimes the binocular operator must be overridden as a member function, such as the assignment operator =. Also, if you need to modify the internal state of the object, you can generally choose to use the class member function to modify.

The principle of operator overloading
In this way, operator overloading is relatively simple. In fact, there are some rules for operator overloading:

1. In C++, the existing C++ operators can only be overloaded, and users are not allowed to define new operators.

2. Most operators in C++ can be overloaded, except for the member access operator, scope operator ::, length operator sizeof, and conditional operator? :.

3. The number of operation objects (operands) of an operator cannot be changed after the operator is overloaded. For example, "+" is an operator that implements two operands and remains a binocular operator after overloading.

4. Overloading cannot change the precedence or associativity of an operator.

5. Operator overloading cannot be all predefined basic data in C++. The purpose of this is to prevent users from modifying the operator properties for data of basic types.

Why operator overloading
There are so many rules for operator overloading, so why do you want to overload operators? Why y didn't I write an add() function instead of an operator +()? In my opinion, the reason why operator overloading is supported in c ++ is to operate with the built-in data types, such as: c = a + b or c = add (a,b). At the same time, we want to be able to manipulate our own defined data types just as easily as we can manipulate built-in data types like int and double. Maybe this is a bad example of an addition, but now the overloading operator is [], < < , ^ and |? What member function should we use instead? What is the effect of substitution? Can you see at a glance what this function is doing?


Related articles: