运算符重载---二元运算符重载

  • 运算符重载基础

(该文档来自于对传智博客视频的整理)

全局函数和类成员函数的区别

//全局函数

//如果把全局函数转成成员函数,少了一个操作数,通过this指针,被隐藏。

Test add(Test &t1, Test &t2)

{

Test t3(t1.getA()+t2.getA(), t1.getB() + t2.getB()) ;

return t3;

}

 

//把成员函数转成全局函数,需要多一个参数。。。。

void printAB(Test *pthis)

{

cout<<"a:"<<pthis->getA()<<"b:"<<pthis->getB()<<endl;

}

  

为什么要有运算符重载

原因: Complex是用户自定义类型。。编译器根本不知道如何进行加减。。。编译器给你提供了一种机制,让用户自己去完成,自定义类型的加减操作。。。。。这个机制就是运算符重载机制。

 

简单的代码如下:

 

#include "iostream"
using namespace std;

//a + bi //复数
class Complex
{
public:
	friend ostream& operator<<(ostream &out, Complex &c1);
	Complex(int a, int b)
	{
		this->a = a;
		this->b = b;
	}
	void printCom()
	{
		cout<<a<<" + "<<b<<"i "<<endl;
	}
	//通过类成员函数完成-操作符重载
Complex operator-(Complex &c2)
	{
		Complex tmp(a - c2.a, this->b - c2.b);
		return tmp;
	}
	Complex operator+(Complex &c2)
	{
		Complex tmp(a + c2.a, this->b + c2.b);
		return tmp;
	}
	//通过成员函数完成前置--
	Complex& operator--()
	{
		this->a--;
		this->b--;
		return *this;
	}
	//通过成员函数完成前置--
	Complex& operator++()
	{
		this->a++;
		this->b++;
		return *this;
	}

	//通过类成员函数完成后置--
	Complex operator--(int)
	{
		Complex tmp = *this;
		this->a--;
		this->b--;
		return tmp;
	}
	//通过类成员函数完成后置--
	Complex operator++(int)
	{
		Complex tmp = *this;
		this->a++;
		this->b++;
		return tmp;
	}

private:
	int a;

	int b;
};

void main61()
{

	Complex c1(1, 2), c2(3, 4);

	//全局函数方法去实现操作符重载
	//1 承认操作符重载是一个函数
	//2 根据操作数,1个操作数 2个操作数,完成函数的参数
	//3 根据函数原型,实现需要业务
	//Complex c31 = operator+(c1, c2);
	Complex c3 = c1 + c2;

	//用类成员函数实现-运算符重载
	Complex c4 = c1 - c2;
	c4.printCom();
	//c1.operator-(c2);

	{
		//问题1 根据类型
		int a = 10, b = 1;
		int c = a + b;
	}

	//前置++ 全局函数
	++c1; 
	c1.printCom();

	//前置-- 成员函数
	--c1;
	c1.printCom();
	//c1.operator--()

	//后置++ 全局函数
	c1++; //operator++(c1);
	c1.printCom();

	//后置-- 类成员函数
	c1--;  //c1.operator--()
	c1.printCom();
system("pause");
}

ostream& operator<<(ostream &out, Complex &c1)
{
	//out<<"12345,生活真是苦"<<endl;
	out<<c1.a<<" + "<<c1.b<<"i "<<endl;
	return out;
}
void main()
{
	Complex c1(1, 2), c2(3, 4);
	int a = 10;
	char *p = "addddd";
	cout<<"a"<<a<<endl;
	cout<<"p"<<p<<endl;

	//Complex自定义类型 。a + bi ab ba
	cout<<c1;
	

	//全局函数 
	//cout<<c1;
	//operator<<(cout, c1);

	//1
	//类成员函数
	//因为你没有方法拿到cout这个类的源码。。。。AOP C++
	//cout.operator<<(c1);

	//2 支持链式编程
	cout<<c1<<"abcc";

	//函数返回值当左值,要求返回一个引用。。。。。
	
	//cout.operator<<(c1).operator<<("abcd");

	//s<<"abcd"

	//s cout.operator<<(c1);

	//s.operator<<("abcd");
system("pause");

}

 

  

编译器如何区分前置++还是后置++?

在C++中重载单目运算符时,会出现前置还是后置的问题,如++,–-等这个时候如何让编译器知道是前置还是后置呢?

其实很简单,只要在重载操作符的参数中加上一个整数型参数,编译器就会自动将这个函数标示为后置,相应的不加则是前置。

 

 

  • 运算符重载在项目开发中的应用

功能1
[]运算符放在=右边和放在=左边。。。。

所以重载函数原型 int& Array::operator[](int i);

//一下是运算符重载函数 

//从数组里面拿元素

int& Array::operator[](int i)

{

return mSpace[i];

}

 

功能2

关键1支持一个=

关键点2

支持多个=号  Array& Array::operator=(Array &a1);

关键点3:释放旧内存

if (this->mSpace != NULL)

{

delete[] mSpace;

this->mLength = 0;

}

}

关键点4:两个函数原型区别

Array& Array::operator=(Array &a1)

Array Array::operator=(Array &a1)

 

Array& Array::operator=(Array &a1)

{

int i = 0;

if (this->mSpace != NULL)

{

delete[] mSpace;

this->mLength = 0;

}

//a1的所有元素赋给a3

this->mLength = a1.mLength;

this->mSpace = new int[a1.mLength];

 

for (i=0; i<this->mLength; i++)

{

mSpace[i] = a1[i];

}

return *this;

}

  

功能34

bool operator==(Array &a2);

bool operator!=(Array &a2);

 

//功能3

//if (a1 == a2)  //功能3

 

bool Array::operator==(Array &a2)

{

if (this->mLength != a2.mLength)

{

return false;

}

for (int i=0; i<this->mLength; i++)

{

if (this->mSpace[i] != a2[i])

{

return false;

}

}

return true;

}

 

// if (a1 != a2) //功能4

bool Array::operator!=(Array &a2)

{

return !(*this == a2);

}

 

posted @ 2016-11-01 21:56  ren_zhg1992  阅读(177)  评论(0)    收藏  举报