Basic tutorial of C + + operator overloading

Posted by Iconoclast on Fri, 11 Feb 2022 10:20:53 +0100

Basic tutorial of C + + operator overloading

The so-called overloading is to give new meaning. Function Overloading allows a function name to have multiple functions and perform different operations in different situations. Operator Overloading is also a truth. The same operator can have different functions.

In fact, we have unknowingly used operator overloading. For example, the + sign can add data of different types (int, float, etc.)<< It is not only a displacement operator, but also can output data to the console with cout. C + + itself has overloaded these operators.

C + + also allows programmers to overload operators themselves, which brings us great convenience.

The following code defines a complex number class. Through operator overloading, you can use the + sign to realize the addition of complex numbers:

#include <iostream>
using namespace std;
class complex{
public:
    complex();
    complex(double real, double imag);
public:
    //Declare operator overloading
    complex operator+(const complex &A) const;
    void display() const;
private:
    double m_real;  //real part
    double m_imag;  //imaginary part
};
complex::complex(): m_real(0.0), m_imag(0.0){ }
complex::complex(double real, double imag): m_real(real), m_imag(imag){ }
//Implement operator overloading
complex complex::operator+(const complex &A) const{
    complex B;
    B.m_real = this->m_real + A.m_real;
    B.m_imag = this->m_imag + A.m_imag;
    return B;
}
void complex::display() const{
    cout<<m_real<<" + "<<m_imag<<"i"<<endl;
}
int main(){
    complex c1(4.3, 5.8);
    complex c2(2.4, 3.7);
    complex c3;
    c3 = c1 + c2;
    c3.display();
    return 0;
}

Operation results:

6.7 + 9.5i

In this example, a complex class complex, M is defined_ Real represents the real part, m_imag represents the imaginary part. The operator overload is declared in line 10 and implemented (defined) in line 21. Looking closely at these two lines of code, you can find that the form of operator overloading is very similar to that of function.

Operator overloading is actually to define a function and realize the desired function in the function body. When the operator is used, the compiler will automatically call this function. In other words, operator overloading is realized through functions, which is essentially function overloading.

The format of operator overload is:

Return value type operator operator name (formal parameter table column){
//TODO: }

Operator is a keyword that is specifically used to define functions that overload operators. We can regard the operator name as the function name. For the above code, the function name is operator +.

Operator overloaded functions are no different from ordinary functions except that the function name has a specific format.

In the above example, we overloaded the operator + in the complex class, which is only valid for complex objects. When c3 = c1 + c2 is executed; Statement, the compiler detects that the left side of the + sign (+ sign has left associativity, so check the left side first) is a complex object, and will call the member function operator + (), which is converted to the following form:

c3 = c1.operator+(c2);

The argument to call the function c2 is c1.

The above operator overloading can also have a more concise definition form:

complex complex::operator+(const complex &A)const{
    return complex(this->m_real + A.m_real, this->m_imag + A.m_imag);
}

The complex (this - > m_real + a.m_real, this - > m_imag + a.m_imag) in the return statement will create a temporary object. This object has no name and is an anonymous object. In the process of creating temporary objects, the constructor is called, and the return statement returns the value of the temporary object as a function.

Overloading operators globally

Operator overloaded functions can be used not only as member functions of classes, but also as global functions. Change the above code, overload + in the global scope, and realize the addition of complex numbers:

#include <iostream>
using namespace std;
class complex{
public:
    complex();
    complex(double real, double imag);
public:
    void display() const;
    //Declare as friend function
    friend complex operator+(const complex &A, const complex &B);
private:
    double m_real;
    double m_imag;
};
complex operator+(const complex &A, const complex &B);
complex::complex(): m_real(0.0), m_imag(0.0){ }
complex::complex(double real, double imag): m_real(real), m_imag(imag){ }
void complex::display() const{
    cout<<m_real<<" + "<<m_imag<<"i"<<endl;
}
//Overload globally+
complex operator+(const complex &A, const complex &B){
    complex C;
    C.m_real = A.m_real + B.m_real;
    C.m_imag = A.m_imag + B.m_imag;
    return C;
}
int main(){
    complex c1(4.3, 5.8);
    complex c2(2.4, 3.7);
    complex c3;
    c3 = c1 + c2;
    c3.display();
    return 0;
}

The operator overloaded function is not a member function of the complex class, but uses the private member variable of the complex class. Therefore, the function must be declared as a friend function in the complex class.

When c3 = c1 + c2 is executed; Statement, if the compiler detects that both sides of the + sign are complex objects, it will be converted to function calls similar to the following:

c3 = operator+(c1, c2);

Summary

Although the functions realized by operator overloading can be replaced by functions, operator overloading makes the writing of the program more humanized and easy to read. After the operator is overloaded, the original function remains without loss or change. Through operator overloading, the function of existing operators in C + + is expanded so that they can be used for objects.

Topics: C++ Back-end