preface
1. Operator overloading is a form of C + + polymorphism.
2. Overloading operators can make the code look more natural.
Review class
During normal class construction, some member methods may not need to be written. For example, in such a class representing time, the copy constructor is only a shallow copy, which is the same as the default steps of the system and may not need to be written. Similarly, if the destructor has nothing to do before the object dies, it can also not be written.
Therefore, in the following example, copy constructs and destructors can be omitted.
class Time { public: Time(); Time(const Time& src) { _hour = src._hour; _minutes = src._minutes; } ~Time(); private: int _hour; int _minutes; };
Introduce operator overloading through examples
Example
To add the characters corresponding to each subscript in two equal arrays, the common writing method is:
#include<iostream> using namespace std; int main(void) { const int SIZE = 10; int ch1[SIZE] = { 0,1,2,3,4,5,6,7,8,9 }; int ch2[SIZE] = { 9,8,7,6,5,4,3,2,1,0 }; int ch3[SIZE]; for (int i = 0; i < SIZE; ++i) { ch3[i] = ch1[i] + ch2[i]; } for (int i = 0; i < SIZE; ++i) { cout << ch3[i] << " "; } cout << endl; return 0; }
This can be output normally:
Let's take a look at the example of operator overloading. Here we use the string class.
#include<iostream> #include<string> using namespace std; int main(void) { string s1 = "aaaa"; string s2 = "bbbb"; string s3 = s1 + s2; cout << s3 << endl; return 0; }
s1 + s2 here is the overload of the addition operator used, and the internal implementation is also the corresponding subscript plus, but such a simple writing emphasizes the essence.
definition
To overload an operator, you need to use a special form of function called an operator function.
Format:
ret_form operator op(argument-list)
For example, the addition operator:
operator +();
Overloadable operator
Here's a joke. List the overloadable ones. If you are interested, you can implement them yourself.
Classes described in this article
The following is a class of the article example:
Represents a complex number
class Complex { public: //Default construction Complex(); //Constructor Complex(int a, int b) { _a = a; _b = b; } //Print void show() { cout << _a << "+" << _b << endl; } //Destructor ~Complex() { cout << "Program Exit" << endl; } private: int _a; //real part int _b; //imaginary part }
Addition operator
If you want to use addition, such as
int main(void) { Complex s1(1, 2); Complex s2(2, 3); Complex s3 = s1 + s2; return 0; }
First of all, make sure that I can't change the original value of the addend. Second, I need to return a added class.
Then the overloaded addition operator declaration can be written as:
1. The return type is class type
2.this pointer is declared const
3. The second addend is declared const
Complex operator +(const Complex& src)const;
Function implementation:
The constructor is also used here, which is constructed and returned.
//Addition operator Complex operator +(const Complex& src)const { int a = _a + src._a; int b = _b + src._b; return Complex(a, b); }
There are two ways to use operators:
Both s3 and s4 can be used
Complex s1(1, 2); Complex s2(2, 3); Complex s3 = s1 + s2; Complex s4 = s1.operator+(s2);
Running example:
s3 and s4 are output and destructed.
&&Operator
For example, write a method to determine whether the real part of two complex numbers is 0
if (s1 && s2) { cout << "all zero" << endl; }
realization:
//&& bool operator &&(const Complex& src)const { return _a && src._a; }
Cout < < operator
To overload the output operator, the first thought is to pass cout to the function as an argument.
Simple version (equivalent to show())
//cout << void operator <<(ostream& out) { out << _a << "+" << _b << "i" << endl; }
If it is overloaded in this way, it can only be called as the show() method. cout cannot be used directly.
Zhenxiang Edition
First of all, you should know that cout is a binary operator. When we pass parameters, we also pass two parameters. To the simple version above, the first parameter is the this pointer and the second is cout. If you want to move the this pointer to the second parameter, you can't do it, so you can only write it as a show method.
void operator <<(/*this*/ostream& out) { out << _a << "+" << _b << "i" << endl; }
resolvent:
Put the parameter to be output in the second position.
Here, it needs to be implemented outside the class. The implemented method uses the friend property and is put into the class.
As shown in the figure, I did write outside the class.
Running example:
Write cout < < S1 directly here
int main(void) { Complex s1(1, 2); Complex s2(2, 3); Complex s3 = s1 + s2; Complex s4 = s1.operator+(s2); s3.show(); s4.show(); //s1.operator<<(cout); cout << s1; return 0; }
No problem, output 1+2i
But if you want continuous output, for example:
cout << s1 << s2;
I can't write as above, because the return type of this method is void. The function parameters first receive cout and s1, then return void, and pass void and s2 as parameters. Obviously, it can't.
resolvent:
Write the return type of this method as an output stream object, that is, ostream
ostream& operator <<(ostream& out, const Complex& src) { out << src._a << "+" << src._b << "i" << endl; return out; }
Similarly, the friend function is also written as:
friend ostream& operator <<(ostream& out, const Complex& src);
If it is written in this way, it can be output continuously
Example: to output three objects
cout << s1 << s2 << s3;
Operation results
++Operator
Front++
Pre + + means to add 1 before returning.
realization:
This is only for the real part of the complex number
//Front++ Complex& operator ++() { ++_a; return *this; }
Post++
Post + + means to pass the value first, and then increase by 1.
realization:
The int in the parameter list has no substantive meaning, but allows the compiler to distinguish between pre and post.
//Post++ Complex operator ++(int) { int tmp = _a; _a++; return Complex(tmp, _b); }
practice
Through these operator overloads described above, you can write other.
Here can be achieved
Subtraction operator, || operator, > > operator and self subtraction operator (- -).
For example, subtraction operator: written in the same way as addition:
//Subtraction operator Complex operator -(const Complex& src)const { int a = _a - src._a; int b = _b - src._b; return Complex(a, b); }