[3] Object oriented programming: operator overloading and temporary objects

Section 5 operators and operator overloading

In C + +, the operator itself is a function that can be customized by users. Then we think that the calculation of complex numbers is not as good as using the + sign directly, and the concept and operation rules of the + sign need operator overloading.

Operator overloading can be written in two ways according to the difference between member functions:

inline complex&
complex::operator += (const complex& r)
{
    return _doapl (this, r);
}

inline complex& //What follows is how the receiver will get the return value.
complex::operator +=(this,const comp)
{
    return _doapl (this, r);
}

In the complex class, define an operator overloaded member function.

All member functions carry a hidden parameter called this. Who calls the function itself, the caller, is this. This can be regarded as the element of a class to be manipulated, pointing to the address of the class element to be manipulated.

The second kind is written. this can be put in the front and in the back.

In addition, this cannot be written in the parameter column, but it can be used in the function.

All binary operators can add the element on the right to the left, and then the class on the left has a pointer to this to complete the address call.

Syntax analysis of return by reference:

The receiver does not need to know in the form of reference.

First, the version of the member function:

inline complex& //Here, it means that the receiving end accepts in the way of reference
_doapl(complex* ths, const complex& r)
{
    ...
    return *ths;
}

Here, the form from the incoming data to the incoming data is reference, and the type of the return value is a dereference form of * ths.

In fact, if you only use + = to assign a value, it can be written as inline void In fact, some strange expressions will be involved, such as:

c1 += c2 += c3; You need to have specific return data written as inline complex & standard.

Second: version of non member function:

inline double
real(const complex& x)
{
    return x.real();
}

inline double
imag(const complex& x)
{
    return x.imag();
}

inline complex
operator + (const complex& x , const complex& y)
{
    return complex(real(x) + real(y), imag(x) + imag(y));
}

inline complex
operator + (const complex& x, double y)
{
    return complex(real(x) + y,imag(x));
}

inline complex
operator + (double x , const complex& y)
{
    return complex(real(y) + x , imag(y));
}

+There are three ways to respond. Possible plural + plural, plural + real, real + plural

Temporary object

The above functions do not return reference, because they must return a local object The generated is a temporary local variable, so it cannot be implemented by reference.

The typename() class directly adds parentheses, which is similar to the declaration of variables. It is equivalent to creating a temporary object based on subsequent data.

Complex (a, b) creates a temporary complex variable a + bi. The life of the temporary variable only exists in the next line.

Various definitions other than class body:

inline complex
operator + (const complex& x)
{
    return x;
}

inline complex
operator - (const complex& x)
{
    return complex(-real(x) , -imag(x));
}

These two symbols are negative and positive symbols, which define unary operators. Binary operators are distinguished by the number of parameters+

Taking positive is itself, and taking negative will create a new object, so the negative operation must pass a value.

inline bool
operator == (const complex& x, const complex& y)
{
    return (x.real() == y.real()) && (x.imag() == y.imag());
}

inline bool
operator == (const complex& x,double y)
{
    return (x.imag() == 0) && (x.real() == y);
}

inline bool 
operator == (double x, const complex& y)
{
    return (x == y.real()) && (y.real() == 0);
}

This is to compare whether two complex numbers are equal. All cases need to be considered.

inline complex
conj (const complex& x)
{
    return complex(real(x), -imag(x));
}

Conjugate complex number. The real part is equal and the imaginary part is opposite.

#include <iostream.h>
ostream&
operator << (ostream& os,const complex& x)
{
    return os << '(' << real(x) << ',' << imag(x) << ')';
}

complex c1(2,1);
cout << conj(c1);

When outputting, you also need to overload the shift left operator. Since the lvalue operation and the class corresponding to cout is ostream, u sends one. We need to provide the reference os of ostream. Then it can be output. Similarly, when the os is shifted to the left, the output stream is actually changed, so there is no need to add const to modify it.

You can't change osteram & to void, because you may encounter continuous left shift operations. When outputting a variable, you still need to maintain an osteram class. So the return type should be ostream&

Therefore, when designing classes, we must consider how users use them.

Keywords: C++ Back-end

Added by srdva59 on Mon, 21 Feb 2022 13:03:14 +0200