C++总结笔记(七)—— 运算符重载


一、概念

C++中运算符重载是为了实现对象之间进行各种运算的特定语法,在某些特定的场合起到重要的作用,新建重载方法需用operator关键字进行修饰。

可以重载运算符包括+、-、*、\、赋值运算符=、左移运算符<<、递增运算符++、递减运算符- -、关系运算符、函数调用运算符()等。

运算符重载需要遵守以下规则:
1 重载时不能违法运算符原来的句法规则。
2 只能重载C++定义的运算符。
3 不能改变运算符原有的优先级。
4 运算符的结合性不能被改变。
5 不能进行重载的运算符:成员运算符(.),(::),条件运算符,sizeof、强制类型转换运算符。
6 运算符的目数(又称“元数”,即运算符所需要的操作数的数目)不能被改变。
7 当重载“()”、“[]、“->”、=时,运算符重载函数必须被声明为类成员。


二、程序示例

1. 加减乘除重载

#include<iostream>
using namespace std;

class MyFloat
{
	//成员函数重载运算符
public:
	//MyFloat operator+(MyFloat& myf)
	//{
	//	MyFloat temp;
	//	temp.N1 = this->N1 + myf.N1;
	//	temp.N2 = this->N2 + myf.N2;
	//	return temp;
	//}

	MyFloat operator-(MyFloat& myf)
	{
		MyFloat temp;
		temp.N1 = this->N1 - myf.N1;
		temp.N2 = this->N2 - myf.N2;
		return temp;
	}

	MyFloat operator*(MyFloat& myf)
	{
		MyFloat temp;
		temp.N1 = this->N1 * myf.N1;
		temp.N2 = this->N2 * myf.N2;
		return temp;
	}

	MyFloat operator/(MyFloat& myf)
	{
		MyFloat temp;
		temp.N1 = this->N1 / myf.N1;
		temp.N2 = this->N2 / myf.N2;
		return temp;
	}

public:
	float N1;
	float N2;
};

//全局函数重载运算符
MyFloat operator+(MyFloat& Myf1, MyFloat& Myf2)
{
	MyFloat temp;
	temp.N1 = Myf1.N1 + Myf2.N1;
	temp.N2 = Myf1.N2 + Myf2.N2;
	return temp;
}

MyFloat operator+(MyFloat& Myf1, int N)
{
	MyFloat temp;
	temp.N1 = Myf1.N1 + N;
	temp.N2 = Myf1.N2 + N;
	return temp;
}

int main()
{
	MyFloat myf1;
	myf1.N1 = float(3.6);
	myf1.N2 = float(3.4);

	MyFloat myf2;
	myf2.N1 = float(3.6);
	myf2.N2 = float(3.4);

	/*MyFloat myf3 = myf1.operator+(myf2);*///本质写法
	/*MyFloat myf3 = operator+(myf1, myf2);*/
	MyFloat myf3 = myf1 + myf2;//简化写法
	MyFloat myf31 = myf1 + 1;
	MyFloat myf4 = myf1 - myf2;
	MyFloat myf5 = myf1 * myf2;
	MyFloat myf6 = myf1 / myf2;

	cout << myf3.N1 << " " << myf3.N2 << endl;
	cout << myf31.N1 << " " << myf31.N2 << endl;
	cout << myf4.N1 << " " << myf4.N2 << endl;
	cout << myf5.N1 << " " << myf5.N2 << endl;
	cout << myf6.N1 << " " << myf6.N2 << endl;
}
7.2 6.8
4.6 4.4
0 0
12.96 11.56
1 1

2. 赋值运算符重载

#include<iostream>
using namespace std;

class MyFloat
{
public:
	MyFloat(float n)
	{
		N = new float(n);
	}

	//赋值运算符
	MyFloat& operator=(MyFloat &myf)
	{
		//先判断是否有堆区的属性
		if (N != NULL)
		{
			delete N;
			N = NULL;
		}
		//深拷贝
		N = new float(*myf.N);
		return *this;
	}

    //如果不加赋值运算符重载,对象的赋值操作会引发内存重复释放的异常。
	~MyFloat()
	{
		if (N != NULL)
		{
			delete N;
			N = NULL;
		}
	}


	float *N;
};

int main()
{
	MyFloat myf1(1.1415);
	MyFloat myf2(2.1415);
	MyFloat myf3(3.1415);

	myf3 = myf2 = myf1;

	cout << *myf3.N << endl;;
	cout << *myf2.N << endl;;

}

3. 递增递减运算符重载

#include<iostream>
using namespace std;

class MyFloat
{
	friend ostream& operator<<(ostream& cout, MyFloat myf);
public:
	MyFloat()
	{
		N = 3.1415;
	}

	//重载前置++运算符,返回类型为引用,是因为如果不加,返回值属于值类型,重载函数运行完后会销毁
	//运行完后N的值始终只会加一次1,如果再调用重载,N的值不会一直加1
	MyFloat& operator++()
	{
		//先进行++计算
		N++;
		return *this;
	}
	//重载后置++运算符,int代表占位参数,用于区分前置后置
	MyFloat& operator++(int)
	{
		//先记录当时的结果
		MyFloat temp = *this;

		//后递增
		N++;
		return temp;
	}

	//重载前置--运算符
	MyFloat& operator--()
	{
		//先进行--计算
		N--;
		return *this;
	}
	//重载后置--运算符,int代表占位参数,用于区分前置后置
	MyFloat& operator--(int)
	{
		//先记录当时的结果
		MyFloat temp = *this;

		//后递减
		N--;
		return temp;
	}


private:
	float N;
};

ostream& operator<<(ostream & cout, MyFloat myf)
{
	cout << myf.N;
	return cout;
}

int main()
{
	//后置重载
	MyFloat myf;

	cout << myf++ << " " << endl;
	cout << myf << endl;

	cout << myf-- << " " << endl;
	cout << myf << endl;

	MyFloat myf1;

	cout << ++myf1 << " " << endl;
	cout << ++(++myf1) << " " << endl;
	//又调用一次++相当于先调用了一次拷贝构造函数,然后再调用重载,拷贝构造函数会重新创建一个拷贝的值的内存,再运行完后销毁。
	//如果重载返回值类型不加&,会直接销毁++myf1的拷贝值,加&,会创建一个指针常量,一直指向内存中的N,返回值也会一直是类中的N,而不是拷贝的N的值。
	cout << myf1 << endl;

	cout << --myf1 << " " << endl;
	cout << myf1 << endl;
}
3.1415
4.1415
4.1415
3.1415
4.1415
4.1415
3.1415
3.1415

4. 关系运算符重载

#include<iostream>
using namespace std;

class MyFloat
{
public:
	MyFloat(float n)
	{
		N = n;
	}

	//等于运算符
	bool operator==(MyFloat& myf)
	{
		if (this->N == myf.N)
		{
			return true;
		}
		else
		{
			return false;
		}	
	}
	//大于运算符
	bool operator>(MyFloat& myf)
	{
		if (this->N > myf.N)
		{
			return true;
		}
		else
		{
			return false;
		}
	}
	float N;
};

int main()
{
	MyFloat myf1(1.1415);
	MyFloat myf2(1.1415);
	MyFloat myf3(3.1415);

	if (myf1 == myf2)
	{
		cout << "myf1与myf2相等" << endl;
	}

	if (myf3 > myf2)
	{
		cout << "myf3大于myf2" << endl;
	}
}
myf1与myf2相等
myf3大于myf2

5. 左移运算符重载

#include<iostream>
using namespace std;

class MyFloat
{
	friend ostream& operator<<(ostream& cout, MyFloat myf);
public:
	MyFloat()
	{
		N = 3.1415*N1;
	}

private:
	float N;
	float N1 = float(2);
};

//重载左移运算符,只能利用全局函数重载。成员函数重载时会发生cout在右侧。
//ostream类只能用引用的方式声明对象。
ostream& operator<<(ostream & cout, MyFloat myf)
{
	cout << myf.N;
	return cout;
}

int main()
{
	MyFloat myf;

	cout << myf << endl;

}
6.283

6. 函数调用运算符重载

#include<iostream>
using namespace std;

class MyFloat
{
public:
	MyFloat(float n)
	{
		N = n;
	}

	//函数调用运算符
    float operator()(float n1,float n2)
	{
		return n1 + n2;
	}

	float N;
};

int main()
{
	MyFloat myf(0);

	float c = myf(float(1.1415), float(1.1415));//与函数调用相似,又称为仿函数

	cout << c << endl;
	cout << MyFloat(0)(float(1.1415), float(1.1415)) << endl;//匿名对象

}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值