[C ++]-operator overloading


Introduction: In the template, we define the following sum function

template<typename T>
T sum(T a,T b)
{
	return a+b;
}

If it is a normal data type, it can be calculated, but what if the objects are added together?
Then it leads to what we want to discuss today-operator overloading

First, operator overloading implements complex number classes

Just like the sum function we discussed in the introduction, we can add two objects by operator overloading.

The meaning of operator overloading : make the operation of the object behave the same as the built-in type of the compiler.
First, let's write a simple complex number operation. The code is as follows:

class CComplex
{
public:
	CComplex(int r = 0,int i =0)
		:mreal(r)
		,mimage(i)
	{}
	void show() { cout << "real:" << mreal << "image:" << mimage << endl; }
private:
	int mreal;
	int mimage;
int main()
{
	CComplex comp1(10, 10);
	CComplex comp2(20, 20);
	CComplex comp3 = comp1 + comp2;	
	comp3.show();
	return 0;
}

But look closely at the above code, we will find that he is wrong in the addition operation.

1. Addition operator overloading

(1) The addition operator overloading
implementation principle of adding two objects : to find if there is a plus sign method in the object of comp1, use comp2 as an actual parameter. Comp1.operatpr + (comp2) The overload function of the addition operator looks like Doing calculations is essentially calling member methods.
It can also be written as CComplex comp3 = comp1.operator + (comp2);
code implementation:

CComplex operator+(const CComplex& src)//引用接收另一个复数类对象
	{
		CComplex comp;//定义一个新对象
		comp.mreal = this->mreal + src.mreal;
		comp.mimage = this->mimage + src.mimage;
		return comp;
	}

The result of the above code optimization is as follows:

CComplex operator+(const CComplex& src)//引用接收另一个复数类对象
	{
		return CComplex(this->mreal + src.mreal,this->mimage+src.mimage);
	}

(2) Adding objects and constants
For example, in the main function we want to implement CComplex comp4 = comp1 +20;
his essence is that comp1 calls the overloading of the addition operator, passing 20 as an argument. Then the type of the actual parameter to the formal parameter is forcibly changed. Convert integer type to complex CComplex type to generate temporary objects

In the constructor, three types of CComplex (), CComplex (20), CComplex (30, 30) can generate constructors and construct three different complex objects

However, when we put the constant before the plus sign, CComplex comp5 = 30 + comp2; The above call will not work.
In this case, the integer is not converted to a complex type. When the compiler performs object operations, it will call the operator overload function of the object (priority to call the member method). If there is no member method, find the appropriate operator overload function in the global scope. The global and local codes can be shielded

Solution: Define an addition operator overloading globally so that both 30 and comp2 are passed in as arguments

The global code is implemented as follows:

CComplex operator+(const CComplex& lhs, const CComplex& rhs)
{
	return CComplex(lhs.mreal + rhs.mreal, rhs.mimage + rhs.mimage);
}

However, because private member variables cannot be accessed outside the class, we use friend functions to solve this problem.
Add friend CComplex operator + (const CComplex & lhs, const CComplex & rhs) to private members;

(3) Object self-increment
We know that ++-is a monocular operator. Here: operator ++ () means pre-++, operator ++ (int) means post-++
The overloaded code of this operator is as follows:

CComplex operator++(int)
	{
	/*	方式一:
	    CComplex comp = *this;
		mreal += 1;
		mimage += 1;
		return comp;*/
		//优化后:
		return CComplex(mreal++, mimage++);//把老对象的值返回过后再实部虚部加加,少了comp对象构造和析构的过程
	}
	CComplex& operator++()
	{
		mreal += 1;
		mimage += 1;
		return *this;
	}

(4) Compound assignment operator
For example, the addition of two objects comp1 + = comp2; this way.
The overloaded operator code is as follows:

	void operator+=(const CComplex& src)
	{
		mreal += src.mreal;
		mimage += src.mimage;
	}

2. Input and output operator overloading

When we want to output the information of an object, we must overload the input and output operators.
Define this overloaded function globally, the code implementation is as follows:

ostream& operator<<(ostream& out, const CComplex& src)
{
	out << "mreal:" << src.mreal << "mimage:" << src.mimage << endl;
	return out;
}
istream& operator>>(istream& in,CComplex& src)
{
	in >> src.mreal >> src.mimage;
	return in;
}

Similarly, since private member variables cannot be accessed outside the class, you must define friend functions in the private member variables.

Second, the operator overloading implements the String class

(1) Implementation of comparison operators

bool operator>(const String& str)const
	{
		return strcmp(_pstr, str._pstr) > 0;
	}
	bool operator<(const String& str)const
	{
		return strcmp(_pstr, str._pstr) < 0;
	}
	bool operator==(const String& str)const
	{
		return strcmp(_pstr, str._pstr) == 0;
	}

(2) [] operator implementation

//char ch = str6[6]; str[6] = '7';
	const char& operator[](int index)  { return _pstr[index]; }
	//char ch = str6[6];但是不允许修改
	const char& operator[](int index) const { return _pstr[index]; }

(3) String concatenation + operator implementation The
first way: lower efficiency

char* ptmp = new char[strlen(lhs._pstr) + strlen(rhs._pstr) + 1];
	strcpy(ptmp, lhs._pstr);
	strcat(ptmp, rhs._pstr);
	String tmp(ptmp);
	delete[]ptmp;//局部对象,记得要内存释放
	return tmp;

Because there are two objects, new and delete.
Note! Only strcat will not work, because _pstr has no extra space at all.

The second way to improve:

String tmp;
	tmp._pstr = new char[strlen(lhs._pstr) + strlen(rhs._pstr) + 1];
	strcpy(tmp._pstr, lhs._pstr);
	strcat(tmp._pstr, rhs._pstr);
	return tmp;

In this way, new and delete memory is realized once less. More efficient.

Published 98 original articles · won praise 9 · views 3669

Guess you like

Origin blog.csdn.net/qq_43412060/article/details/105126634