美文网首页
16 类和对象--运算符重载

16 类和对象--运算符重载

作者: ca8519be679b | 来源:发表于2020-11-01 14:07 被阅读0次

<对于数字我们的运算符加减乘除等等都是有意义的,但是如果符号想应用于自定义的数据类型,完成某种意义上的操作呢,就需要运算符重载

加法运算符重载

1

如上图,对于已有的int,我们使用符号就好了,比如对于Person类,我们定义2个属性,并想通过对象加法完成新对象的属性分别为2者之和。那我们可能就会想到上图的定义一个PersonAddPerson方法,最后返回对象即可,然而我们这么麻烦,其实可以使用编译器已经准备好的函数名 operator+,而我们调用的时候,使用+即可

2

如上代码就是个简单的实现,最后不要滥用运算符重载,如加变减这种。

左移运算符重载

我们打印输出使用过cout<<p<<endl;如果p对象有属性,我们想输出p对象的属性值,就可以使用左移运算符的重载

3

如上,我们想定义Person的重载,因为不能写在类成员函数,所以只能使用全局函数重载,我们给operator<<传入2个参数,左侧为cout,右侧为Person p的引用,我们cout并不是简单写cout,所以要右键查看定义,可以看到其为ostream类型,我们这里需要使用引用,因为我们不需要创建新的输出流,然后我们内部使用输出流的本身特性接口,就实现了输出属性的操作。当然这只是在cout<<p,我们再想在右侧调用<<就会报错了

4

可以看到如上报错,其实这里就涉及到之前的返回自身的对象的思想,我们继续返回输出流本身就好了,就能使用ostream自身的在<<左侧的输出

5

其实这就是cout输出流本身的一种实现返回自身的引用,我们将void 改成ostream &即可,

重载递增运算符

我们想自定义一个整数类MyInteger,然后实现递增++,但是左加和右加必须有区别,我们先实现左加

6

如上,我们想输出一个自定义类,我们需要重构<<方法,上节课已经讲过了重载左移,需要全局函数传递,而且使用友元使其能访问到私有属性num。这里左加对应得就是operator++,我们可以考虑返回值或者返回对象,这里我们选择返回自身,这是因为,如果返回int值,则多次递增就变成了int数值的递增,而对象只递增一次,我们需要在++(++mint)这种情况下,mint的num变成2,最终修改完实现。

接下来重载右加,关于右加,你会困惑了,我们好像也就会operator++,但是不传参又会报重复定义错误,其实c++对于右加使用operator++(int)来区别左加,表示是右加。

7

如上,我们这里右加反而不能返回自身,这是因为,我们要实现this.num自加,但是如果先return了,就没有这种操作,只能把临时值存储之前状态,然后返回值,但是mint本身的num也实现自加了

重载赋值运算符

什么时候需要重载赋值运算符呢,我们类对象=某种情况时,需要考虑赋值操作的问题,

8

如上,我们定义一个简单的Person类,定义构造方法,然后可以输出属性

9

如果我们把属性开辟到堆区,就把属性变成指针,new int接收地址,然后析构里判断指针不为NULL,就释放,然而我们test函数里使用的是p2,传入p1,使用拷贝方法,这种就引发了异常,当然很明显了你也能知道,这是我们之前讲过了,释放空间时,拷贝为浅拷贝的把属性地址也拷贝了,一个析构释放了空间,另一个还尝试释放相同的空间,就会报错。这时就需要我们使用深拷贝,将赋值操作指针的空间变成新开辟空间

10

如上,我们重载=,需要传入引用Person类型,同时返回的也必须是个引用,因为我们希望能使用连等,这里还需要做个判断,如果当前已经有指向了,需要先清空所占堆区,将指向新开辟空间

其实类初始化时默认就有了4个方法,无参,析构,拷贝和赋值

重载关系运算符

我们都知道基本数据类型的比较啊与或非等等,返回的都是bool型,我们对自定义的类型就需要重载运算符来实现关系比较等等

11

没啥说的

重载函数调用操作符

函数调用操作符,其实就是一对小括号

12

如上,我们编写一个类MyPrint类,这样,我们就能使用重载调用操作符,来实现类似函数功能的操作,我们又把这种类似函数的使用叫做仿函数。

13

如上,我们知道匿名对象,我们重载了调用方法的再使用匿名对象就是创建了匿名函数。

当然重载调用有很多种应用,就不一一列举了。

相关文章

网友评论

      本文标题:16 类和对象--运算符重载

      本文链接:https://www.haomeiwen.com/subject/zbzzmktx.html