C Quack's operator overloading basic tutorial and compliance with the rules [three books at the end of the article]

Blogger name: Ah Yue's Xiaodongdong

Let's make progress together!

Table of contents

basic concept

Priority and associativity

won't change the usage

Overloading operators globally

summary

Book delivery in this issue: The latest version of Core Java Volume II, which has been looking forward to for a year, is finally on the market


basic concept

Operator overloading is achieved through function overloading, which is easy for everyone to understand conceptually. In this section, we will talk about the precautions for operator overloading.

1) Not all operators can be overloaded. Operators that can be overloaded include:
+ - * / % ^ & | ~ ! = < > += -= *= /= %= ^= &= |= << >> <<= >>= == ! = <= >= && || ++ -- , ->* -> () [] new new[] delete delete[]

Among the above operators, []they are subscript operators and ()function call operators. Both the pre-increment and post-decrement operators can be overloaded. Length operators sizeof, conditional operators : ?, member selectors ., and field resolution operators ::cannot be overloaded.

Priority and associativity



2) Overloading cannot change the precedence and associativity of operators. Suppose +the sign and *sign are overloaded in the complex class in the previous section, and c1, c2, c3, and c4 are all objects of the complex class, then the following statement:

c4 = c1 + c2 * c3;

Equivalent to:

c4 = c1 + ( c2 * c3 );

Multiplication still has higher precedence than addition, and they are still binary operators.

won't change the usage



3) Overloading will not change the usage of the operator, the original number of operands, whether the operand is on the left or on the right, these will not change. For example, ~there is only one operand to the right of the number, and +the number always appears between the two operands, and it must be the same after overloading.

4) Operator overloading functions cannot have default parameters, otherwise the number of operator operands will be changed, which is obviously wrong.

5) The operator overloading function can be used not only as a member function of a class, but also as a global function.

When the operator overloading function is used as a member function of a class, the binary operator has only one parameter, and the unary operator does not need a parameter. The reason why there is one less parameter is because this parameter is implicit.

For example, the addition operator is overloaded in the complex class from the previous section:

complex operator+(const complex & A) const;

When executing:

c3 = c1 + c2;

would be converted to:

c3 = c1.operator+(c2);

Access the member variables of c1 implicitly through this pointer.

When the operator overloading function is used as a global function, the binary operator needs two parameters, and the unary operator needs one parameter, and one of the parameters must be an object, so that the compiler can distinguish that this is a programmer-defined operator. Prevents programmers from modifying the nature of operators used on built-in types.

For example, the following is incorrect:

 
 
  1. int operator + (int a,int b){
  2. return (a-b);
  3. }

+The original number is to add two numbers, and now it is trying to change its function to subtract two numbers through overloading. If this overloading is allowed, then 4+3is the result of the expression 7 or 1? Obviously, this is absolutely forbidden.

If there are two parameters, both parameters can be objects, or one can be an object and the other can be data of a built-in C++ type, for example:

 
 
  1. complex operator+(int a, complex &c){
  2. return complex(a+c.real, c.imag);
  3. }

What it does is add an integer and a complex number.

In addition, when an operator overloaded function is used as a global function, it is generally necessary to declare the function as a friend function in the class. The reason is simple, the function needs to use the private members of the class in most cases.

In the last example of the previous section, we overloaded +the number in the global scope, and declared the operator overloading function as a friend function in the complex class, because this function uses the two member variables m_real and m_imag of the complex class, they They are all private attributes and cannot be accessed outside the class by default.

6) Arrow operators ->, subscript operators [ ], function call operators ( ), and assignment operators =can only be overloaded in the form of member functions.

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

In effect, we're already using operator overloading without knowing it. For example, +number can perform addition operation on data of different types (int, float, etc.); it <<is not only a shift operator, but also can cooperate with cout to output data to the console. 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, +the addition operation of complex numbers can be realized by numbers:

 
 
#include <iostream>
using namespace std;

class complex{
public:
complex();
complex(double real, double imag);
public:
//声明运算符重载
complex operator+(const complex &A) const;
void display() const;
private:
double m_real; //实部
double m_imag; //虚部
};

complex::complex(): m_real(0.0), m_imag(0.0){ }
complex::complex(double real, double imag): m_real(real), m_imag(imag){ }

//实现运算符重载
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;
}

Running result:
6.7 + 9.5i

In this example, a complex class complex is defined, m_real represents the real part, m_imag represents the imaginary part, line 10 declares operator overloading, and line 21 implements (definition). Carefully observe these two lines of code, you can find that the form of operator overloading is very similar to that of functions.

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. That is to say, operator overloading is achieved through functions, which is essentially function overloading.

The format of operator overloading is:

return value type operator operator name (formal parameter list) {     //TODO: }

operatoris a keyword specifically used to define functions that overload operators. We can think operator 运算符名称of this part as the function name, and for the above code, the function name is operator+.

Operator overloading 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 +, and this overload is only valid for complex objects. When c3 = c1 + c2;the statement is executed, the compiler detects that +the left side of the number ( +the number has left associativity, so the left side is detected first) is a complex object, and then calls the member function, operator+()which is transformed into the following form:

c3 = c1.operator+(c2);

c1 is the object to call the function on, and c2 is the actual parameter of the function.

The operator overloading above can also be defined in a more concise form:

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

The return statement complex(this->m_real + A.m_real, this->m_imag + A.m_imag)will create a temporary object, which has no name and is an anonymous object. The constructor is called during the creation of a temporary object, and the return statement uses the temporary object as the return value of the function.

Overloading operators globally

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

 
 
#include <iostream>
using namespace std;

class complex{
public:
complex();
complex(double real, double imag);
public:
void display() const;
//声明为友元函数
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;
}

//在全局范围内重载+
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 overloading function is not a member function of the complex class, but uses the private member variable of the complex class, so the function must be declared as a friend function in the complex class.

When c3 = c1 + c2;the statement is executed, the compiler detects that +there are complex objects on both sides of the number, and converts it into a function call similar to the following:

c3 = operator+(c1, c2);

summary

Although the functions implemented by operator overloading can be completely replaced by functions, operator overloading makes the writing of programs more humane and easy to read. After the operator is overloaded, the original function is still retained, not lost or changed. Through operator overloading, the functions of existing operators in C++ are expanded so that they can be used for objects.

Book delivery in this issue: The latest version of Core Java Volume II, which has been looking forward to for a year, is finally on the market

Books for this issue: Three books for this issue: "Java Core Technology Volume II Advanced Features (12th Edition of the Original Book")

ways to obtain:

The top two with high-quality comments + likes will each get a copy!

Randomly select a good brother in the comment area to send a book!

Draw time: May 10 at 8:00 p.m.

Since the birth of Java 28 years ago, this world-renowned Java classic book "Core Java" has been accompanied by the growth of Java all the way, and has been favored by millions of Java developers. It has become a best-selling Java classic book and has influenced several generations of technology. people.

The latest Chinese version of "Java Core Technology (12th Edition of the original book) has been fully revised to cover the new features of Java 17. The new version continues the fine tradition of the previous version, using hundreds of actual engineering cases to comprehensively and systematically explain the core concepts, syntax, important features, and development methods of the Java language.

Focus on enabling readers to flexibly apply the advanced features provided by Java on the basis of fully understanding the Java language and Java class library, including object-oriented programming, reflection and proxy, interface and inner class, exception handling, generic programming, collection framework , the event listener model, GUI design, and concurrency.

The latest version of Core Java, Volume II, is now available

The father of Java also said earlier that developers should abandon JDK 8 as soon as possible, and can choose the long-term support version of JDK 17. The 12th edition of the latest edition of "Core Java", which is comprehensively updated for the new features of Java 17, has caused a sensation since it was released in May last year. It has received high attention from tens of thousands of readers, and everyone left messages looking forward to the release of Volume II!

For experienced programmers, if you want to write robust code for practical applications, "Java Core Technology" is definitely an industry-leading, concise book. Now, it's finally here! "Java Core Technology Volume II Advanced Features (12th Edition of the original book)" is now on the market, and all major channels are in stock.

Volume II has been revised for new features and improvements in Java 17. As before, all chapters have been fully updated to remove obsolete content and discuss various new APIs in detail.

What is the difference between Volume I and Volume II?

How to read "Java Core Technology"

After finishing this book, you will become a real Java programmer. This book not only gives you an in-depth understanding of all the basics and Java features involved in designing and implementing Java applications, but also helps you master all the basic skills you need to develop Java programs. I believe that with the help of this book on the road of learning Java, your learning will definitely be able to achieve twice the result with half the effort.

Guess you like

Origin blog.csdn.net/m0_64122244/article/details/130544852