C + +: introduction to operator overloading

Keywords: C++ Back-end

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);
	}

Posted by lovelyvik293 on Wed, 10 Nov 2021 21:23:17 -0800