Dark horse programmer C + + learning record: class and object part5 operator overloading

4.5 operator overloading

1. Overload of plus operator

2. Shift left operator overload


cout: standard output stream object. There can only be one object globally, so it can only be passed by reference

Always add input to the back: the idea of chain programming:

Chain programming idea: it is to pass multiple operations (multiple lines of code) through dot (.) Link together to become a sentence of code, making the code readable. a(1).b(2).c(3)
Features of chain programming: the return value of a method is block. Block must have a return value (its own object) and a block parameter (the value to be operated)
Representative: Masonry framework.

You can also change cout in the overloaded function to out (the reference is an alias)

Put m_a and M_ After B is changed to private, you need to set the overloaded function as a friend

3. Increment operator overloading (how to distinguish between pre post and post increment is problematic)

Functions to be realized:

You can perform pre increment or post increment operations on the shaping data in the object of the class, and finally output this data (post increment is more difficult to implement)

Steps:

Overload shift left operator
Overload increment operator: first perform + + operation, and then return itself (return reference);
If you do not return a reference and the return value cannot be nested: each time you return a new variable, the value of this variable = the return value;

Difficulties:

Use the placeholder parameter int to distinguish between pre and post increment
Realization of post increment; First record the current value, perform incremental operation and return the recorded value;

review:

1. Different return values cannot be used as a condition for function overloading
Four conditions of function overloading: the same function name, different number of formal parameters, different types of formal parameters and different order of formal parameters
2. Placeholder parameters: placeholder parameters have only parameter type declarations, but no parameter name declarations

Question: (not understood)

Solution: add const to the second parameter of the left shift overloaded function.
reason:
Because when cout < < myint + +, it is equivalent to calling the "ostream & operator < < (ostream & cout, const myintger & myint)" function, and myint + + is passed in as its second parameter. myint + + is also equivalent to calling "MyIntger operator++(int)". The result is the return of a value type, and the value itself is read-only. Therefore, when calling the operator < < function, the formal parameter must be added const.

#include<iostream>
using namespace std;

class Myinteger
{
public:
	Myinteger()
	{
		m_a = 0;
	}
	friend ostream  & operator<< (ostream& cout, Myinteger& myint);
	//Overloading the increment operator is done with member functions
	Myinteger& operator++()
	{
		m_a++;
		return *this;
	}
	//Overload post increment operator
	//Void operator + + (int) int represents a placeholder operation, which can be used to distinguish between pre increment and post increment.
	//Function overload conditions: the function name is the same, the number of formal parameters is different, the type of formal parameters is different, and the order of formal parameters is different
	//Obviously, pre increment and post increment are not simple function overloading
	Myinteger operator ++(int)
	{
		Myinteger temp = *this;
		m_a++;
		return temp;
	}


private:
	int m_a;
};

// Overload shift left operator
ostream  & operator<< (ostream & cout, Myinteger  & myint)
{
	cout << myint.m_a;
	return cout;
}


void test01()
{
	Myinteger myint;
	cout << ++myint <<endl;
	cout << myint;
}
void tesr02()
{
	Myinteger myint;
	cout << myint++ << endl;;
	cout << myint;
}
int main()
{
	test01();
	system("pause");
	return 0;
}

4. Overload of assignment operator

review:

The c + + compiler adds at least four functions to a class
Default constructor (no parameters, empty function body)
Default destructor (no parameters, empty function body)
The default copy constructor copies the value of the attribute
operator =, copy the value of the attribute

Purpose:

If there are attributes in the class pointing to the heap, there will be a deep and shallow copy problem (repeated release of heap data)

solve the problem:

How to reload
When to reload

#include<iostream>
using namespace std;
class person
{
public:
	person(int age) //A data constructor is passed in
	{
		m_age = new int(age);//Open up memory in the heap to store this data, and let the pointer maintain the data in the heap
	}                        //The data opened up in the heap area will return a corresponding type pointer. Here, an int * type data will be returned (m_age is also this type)
	int* m_age;

	person& operator=(person& p) //Overloaded function note: it should be passed in the form of reference or pointer here
	{ 
 //1. Note: the parameters of the overloaded function here must be passed in the form of reference or pointer!!
//2. Otherwise, a copy is made when passing in. When passing in the value of p2 on the right of the assignment, the attribute m of p2 recorded by the temporary variable_ Age's address
//3. When the assignment operator comes out, the overloaded function will be destructed once. At this time, the space from the property new of p2 has been released
//If there is no reference, an error will be reported. If there is no reference, the shallow copy will be called and released again
		if (m_age != NULL) //When we want to realize p1=p2, we must first delete the value of p1, and then accept the value of p2;
		{
			delete m_age; //Free up the memory of this address
			m_age = NULL;// Leave this variable empty
		}
		m_age = new int(*p.m_age);
		return *this;
	}
	~person() //Destructor
	{
		if (m_age != NULL)
		{
			delete m_age;
			m_age = NULL;
		}
	}
};
void test01()
{
	person p1(18);
	person p2(28);
	person p3(20);
	p1 = p2=p3;
	cout << "p1 Age:" <<*p1.m_age << endl;
	cout << "p2 Age:" << *p2.m_age << endl;
	cout << "p3 Age:" << *p3.m_age << endl;
}
int main()
{
	test01();
	system("pause");
	return 0;
}

5. Overloading of relational operators

Custom data types, the compiler does not know how to compare.

"=="
"!="

#include<iostream>
using namespace std;
class person
{
public:
	person(string name,int age)
	{
		m_name = name;
		m_age = age;
	}

	bool operator==(person& p)
	{
		if (this->m_name == p.m_name && this->m_age == p.m_age)
		{
			return true;
		}
		else return false;
	}
	bool operator!=(person& p)
	{
		if (this->m_name != p.m_name||this->m_age == p.m_age)
		{
			return true;
		}
		else return false;
	}
	string m_name;
	int m_age;
};

void test01()
{
	person p1("zhang" ,15);
	person p2("liu", 17);
	if (p1==p2)
	{
		cout << "p1 and p2 equal" << endl;
	}
	else { cout << "p1 and p2 Unequal" << endl; }
	if (p1 != p2)
	{
		cout << "p1 and p2 Unequal" << endl;
	}
	else { cout << "p1 and p2 equal" << endl; }
}

int main()
{
	test01();
	system("pause");
	return 0;
}

6. Function call operator overloading

  • The function call operator () can also be overloaded
  • Because the method used after overloading is very similar to the call of function, it is called imitation function
  • Imitation function has no fixed writing method and is very flexible
  • See: type + () should think of anonymous function objects
#include<iostream>
using namespace std;
class print //Overload 1
{
public:
	void operator()(string text)
	{
		cout << text << endl;
	}
};
void test01()
{
	print p1;
	p1("hello world");
}
class add //Heavy load 2
{
public:
	int operator()(int a, int b)
	{
		return a + b;
	}
};
void test02()
{
	add p2;
	cout << p2(4, 9) << endl; 
	// Anonymous object call
		cout << "add()(100,100) = " << add()(100, 100) << endl;                      
}
int main()
{
	test01();
	test02();
	system("pause");
	return 0;
}

Keywords: C++

Added by Pintonite on Fri, 04 Mar 2022 11:40:33 +0200