【C++】类和对象(六):运算符重载1

大家好,我是苏貝,本篇博客带大家了解C++的运算符重载,如果你觉得我写的还不错的话,可以给我一个赞👍吗,感谢❤️
在这里插入图片描述


(A) 引入

写一个Date日期类,问:如果我们想比较两个日期d1、d2是否相等,可以直接d1==d2吗?
在这里插入图片描述
在这里插入图片描述

不能,因为C++的运算符只能对内置类型使用,对自定义类型会报错。所以我们如果想比较两个日期的大小,就要自己写函数

下面的函数写在全局域里,形参用引用而非对象的传值传参,因为如果是传值传参,那就需要调用对象的拷贝构造,如果用引用就不需要。
函数体内对象的引用x和y能直接访问成员变量的原因是Date类中,成员变量是public
因为函数内只需要对相应的成员变量做比较,不需要改变它们的值,因此形参用const修饰,来保证它们不能被修改

在这里插入图片描述
在这里插入图片描述

写好了比较函数之后,我们就可以比较两个日期的大小了

在这里插入图片描述

在这里插入图片描述

我们这三个函数的函数名写的还不错,能明白是什么意思,那如果现在有人写了这三个函数,但是函数名分别是func1、func2、func3,我们就不能明白这三个函数分别是什么意思。如果C++能让我们对自定义类型使用==、<、>等运算符,那就再好不过了

(B) 运算符重载

C++为了增强代码的可读性引入了运算符重载,运算符重载是具有特殊函数名的函数,也具有其返回值类型,函数名字以及参数列表,其返回值类型与参数列表与普通的函数类似。

函数名字为:关键字operator后面接需要重载的运算符符号。
函数原型:返回值类型 operator操作符(参数列表)

将上面的3个函数分别写成运算符重载
在这里插入图片描述

在这里插入图片描述

写完了3个运算符重载后,就可以直接用运算符来比较2个日期了,也可以用函数
看下图,为什么会报错?
在这里插入图片描述

因为<<的优先级比==、>、<都要高,因此把<<和d1结合到一起,这是不符合我们的要求的。只需要把表达式用括号括起来即可解决这一问题
在这里插入图片描述

注意:
是双操作数的操作符时,操作符左右两边的对象要和函数形参的顺序相同,左边对应第一个形参,右边对应第二个形参

为什么编译器能识别对自定义类型的重载后运算符呢?可以理解为,编译器将cout<<(d1== d2)<<endl转换为cout<<oprator==(d1,d2)<<endl

我们以上的3个运算符重载都是定义在全局域,在函数里能用类的成员变量是因为成员变量的访问权限是public,现在将它们的访问权限改为private,3个运算符重载该做什么修改呢?

修改1:
3个运算符重载任然放在全局域,在类里写返回值是成员变量的值的函数

在这里插入图片描述

为什么会报错?提示说不能将this指针从const Date转换为Date&,即引用x的类型是const Date,调用成员函数GetYear时,形参this指针的类型是Date。从const Date到Date,权限放大,报错

在这里插入图片描述

因此,解决报错的方法:将运算符重载的形参的const去掉

在这里插入图片描述

修改2:
将3个运算符重载放到类里

在这里插入图片描述
在这里插入图片描述

为什么会报错?报错提示说oprator==的参数太多。因为 == 、>、<等都是双操作数的操作符,所以操作数只能有2个,this指针是“成员函数”隐含的第一个指针形参,再加上我们写的x,y一共有3个操作数,所以报错。
解决方法,去掉x,因为x和this都是指向调用成员函数的对象

在这里插入图片描述

在这里插入图片描述

为什么可以用d1==d2呢?运算符重载不是定义在类里吗?一般在查找函数时,如果不指定类域,是不会到类里面查找的。在这里不一样,当有运算符重载时,如果全局域里有就用全局域的,如果没有就到操作数对应类里面找,还找不到就报错

注意:

  1. 不能通过连接其他符号来创建新的操作符:比如operator@ (新的操作符必须在C/C++中也当作操作符使用)
  2. 重载操作符必须有一个类类型参数
  3. 用于内置类型的运算符,其含义不能改变,例如:内置的整型+,不能改变其含义如-
  4. 作为类成员函数重载时,其形参看起来比操作数数目少1,因为成员函数的第一个参数为隐藏的this
  5. .* :: sizeof ?: . 注意以上5个运算符不能重载。这个经常在笔试选择题中出现。
    注意:第一个.不是,*可以重载

好了,那么本篇博客就到此结束了,如果你觉得本篇博客对你有些帮助,可以给个大大的赞👍吗,感谢看到这里,我们下篇博客见❤️

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值