运算符重载概念:
对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型
(如让两个Person类型的数据相加,编译器不知道该如何操作,这就需要用到运算符重载技术)
函数重载条件:函数名,传入的参数(返回值类型不能作为重载条件)
如下图,第二个则不能再作为函数重载(函数名与传入参数都与上一个函数一样)
1、加号运算符重载
作用:
实现两个自定义数据类型相加运算
本质:
利用编译器给的特定函数名operator+,来写希望+实现的功能,该函数完成后+被赋予新的含义
通过成员函数重载+号
(传入一个参数)
通过全局函数重载+号
(传入两个参数)
运算符重载也可以发生函数重载
(改变传入参数类型)
2、左移运算符重载
作用:
可以输出自定义的数据类型
左移运算符<<
目的:
使用cout<<p输出p这个对象的所有属性
不能使用成员函数重载左移运算符
只能利用全局函数重载左移运算符,
注意:cout属于ostream类(输出流)且cout对象只能存在一个所有写函数时要用引用的方法
3、递增运算符重载
作用:实现对自定义的类型自加或自减
重载前置++运算符
注意返回的是引用,若返回的是一个数,输出的++(++myint)为2而再输出myint则是1,因为返回的是一个数后一次的++是针对返回的这个数,而不是myint本身,所以myint实际上只执行了一次自加
重载后置++运算符
注意:
区分前置和后置递增:传入占位参数int
重载后置++运算符函数返回一个值,是因为重载后置++运算符使用了temp,最后返回的也是temp,而temp作为一个成员使用后被立即释放,无法返回引用
4、赋值运算符重载
因为编译器提供的是浅拷贝,若有数据储存在堆区用指针访问,此时进行赋值操作会出现浅拷贝的问题,堆区内存重复释放
所以要重载赋值运算符,使=进行深拷贝
注意:为了能完成链式赋值操作,返回值应为对象本身,返回值类型也应为对象所属的类Person,也应该用引用的方式
5、关系运算符重载
作用:重载关系运算符,可以让两个自定义类型对象进行对比操作
目的:判断两个Person类型的对象各个属性是否相等
利用bool函数,在函数内将对象的各个属性进行分别比较
6、函数调用运算符重载
特点
- 函数调用运算符()也可以重载
- 由于重载后使用的方式非常像函数的调用,因此称为仿函数
- 仿函数没有固定写法,非常灵活(函数可以写为任何功能)
由于使用起来非常像函数调用,因此称为仿函数
如下图:myPrint("hello world");是myPrint这个对象使用了重载的()符号来打印了“hello world”
而MyPrint("hello world");是执行了MyPrint这个函数
还可以将()重载为加法功能
匿名函数对象
匿名对象:
类名加()为匿名对象
匿名对象使用后立即被释放
上面的例子都是实例化了一个myadd对象,用这个对象来使用重载后的(),但是这个实例化的对象在使用()后没有用处,所以也可以不创建对象,使用可以使用匿名对象,使用后匿名对象被释放
因为这个匿名函数重载了()为匿名函数,所以称其为匿名函数对象
总结
对于内置的数据类型的表达式的运算符是不可以改变的
不要滥用运算符重载(加法写成其他运算方式)