类和对象—4

Posted 麋璐

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了类和对象—4相关的知识,希望对你有一定的参考价值。

       今天我们聊主要聊聊有关赋值运算符重载的问题,在我看来赋值运算符写起来不是很难,要注意的点比较多;但是只要主意好要写的点,赋值运算符重载的问题还是很简单的。(代码测试在vs2013编译器上执行)

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

函数名为:关键字operator+需要重载的运算符符号

函数原型:返回值类型operator操作符

我们先来看一个简单的例子:

类和对象—4_赋值

上图是一个最简单的实现赋值运算(注意:如果我们直接Date d2=d1,那么这一步就会变成调用拷贝构造函数),当我们调试时,会发现d2=d1这一操作,编译器并没有调用函数 类和对象—4_操作符_02

我们再来用之前写过的栈类来进行解释

                 类和对象—4_赋值_03

当我们调试时:

        类和对象—4_赋值_04

       s1原封不动的把它的信息都交给了s2,这时,s2的内存空间就找不到了,就会出现内存泄漏的问题;并且当释放空间时,先释放s2空间,再释放s1空间就出现多次释放内存空间的问题(浅拷贝),所以普通的拷贝构造函数肯定不可以,我们就要使用赋值的方式。

       我们来总结一下,如果类中未涉及到资源管理时(Date类),赋值操作是否显式提供都可以,可以不写,直接由编译器完成赋值操作即可;如果类中涉及到资源管理时(Stack类),用户必须显式实现,否则编译器默认生成的赋值操作是浅拷贝,会存在地址空间多次释放。

综上就引入了我们今天的内容,运算符重载。

当我们比较两个自定义变量时,如果不是简单的两数比较,系统无法判断如何比较,这时我们就需要自定义比较方法

类和对象—4_赋值_05

并且当我们要使用时,还需要调用IsEqual函数。而如果我们使用赋值运算符重载时,我们可以在外部定义(成员变量必须为public作用域)

       类和对象—4_赋值_06

       我们在比较两个类对象大小时,就不用自己调用了,系统会为我们调用。这就是使用运算符重载的目的:自己设置规则,告诉编译器,自定义对象遇到该运算符时应该如何操作。

在编写运算符重载时,我们应该注意

1.不能通过连接其他符号来创建新的操作符,比如operator@

2.重载操作符必须有一个类类型或者枚举类型的操作数(否则会出现无限递归),举个例子:

类和对象—4_操作符_07

3.用于内置类型的操作符,其含义不能改变,例如:

        类和对象—4_操作符_08

我们在使用时就会出现,a-b—>a+b,而且在调试时很难发现(这样的错误很难在调试时被关注)。

4.作为类成员的重载函数时,其形参看起来比操作数数目少1成员函数(操作符有一个默认形参this,限定为第一个形参),按上述类举例,内置重载函数可以变为:

类和对象—4_操作符_09

5.C++中有很多运算符,其中这五个运算符不能重载:.*    ::     sizeof     ?:  .   这五个比较典型。

接下来我们再看,正常的我们可以将a=b=c做到连续赋值,但是当我们想让类的对象进行这样的简单赋值却不可以:

类和对象—4_赋值_10

会出现报错,那么我们该怎么进行这类赋值呢?

上述我们写的赋值运算符肯定是不行的,上述其实是将d1赋值给d2,这时类型就变成了viod,再给Date d3赋值时,类型就不一样了。

所以,我们修改赋值运算符重载,让它符合我们的要求:

        类和对象—4_运算符重载_11

       所以,以自定义类型作为函数的参数,尽量传递引用,因为在传参时,不需要拷贝临时对象;如果不想通过形参修改外部实参,最好给形参加const—参考之前讲过的拷贝构造函数参数。如果自定义类型作为函数的返回值类型时,能引用的尽可能引用,这样可以增加效率。

接下来我们再来看一个特殊的赋值运算符重载:前置++和后置++

类和对象—4_运算符重载_12

以上内容就是今天的全部内容,希望大家可以多多阅读,理解;有不对的地方希望大佬可以在评论区留言,感谢大家的观看!!!


以上是关于类和对象—4的主要内容,如果未能解决你的问题,请参考以下文章

C++类和对象

抽象类和接口

抽象类和接口比较

抽象类和接口联系与区别

「实验 4 类和对象-2」

java中类和对象如何协同工作, 这样工作有什么好处?