类和对象—4

少年意气强不羁,虎胁插翼白日飞。这篇文章主要讲述类和对象—4相关的知识,希望能为你提供帮助。
        今天我们聊主要聊聊有关赋值运算符重载的问题,在我看来赋值运算符写起来不是很难,要注意的点比较多;但是只要主意好要写的点,赋值运算符重载的问题还是很简单的。(代码测试在vs2013编译器上执行)
首先我们来看运算符重载的定义:C++为了增强代码的可读性引入了运算符重载,运算符重载时具有特殊函数名的函数,也具有其返回值类型,函数名字以及参数列表,其返回值类型与参数列表与普通函数类似。
函数名为:关键字operator+需要重载的运算符符号
函数原型:返回值类型operator操作符
我们先来看一个简单的例子:

上图是一个最简单的实现赋值运算(注意:如果我们直接Date d2=d1,那么这一步就会变成调用拷贝构造函数),当我们调试时,会发现d2=d1这一操作,编译器并没有调用函数 
我们再来用之前写过的栈类来进行解释
                                 
【类和对象—4】当我们调试时:
               
        s1原封不动的把它的信息都交给了s2,这时,s2的内存空间就找不到了,就会出现内存泄漏的问题;并且当释放空间时,先释放s2空间,再释放s1空间就出现多次释放内存空间的问题(浅拷贝),所以普通的拷贝构造函数肯定不可以,我们就要使用赋值的方式。
        我们来总结一下,如果类中未涉及到资源管理时(Date类),赋值操作是否显式提供都可以,可以不写,直接由编译器完成赋值操作即可;如果类中涉及到资源管理时(Stack类),用户必须显式实现,否则编译器默认生成的赋值操作是浅拷贝,会存在地址空间多次释放。
综上就引入了我们今天的内容,运算符重载。
当我们比较两个自定义变量时,如果不是简单的两数比较,系统无法判断如何比较,这时我们就需要自定义比较方法

并且当我们要使用时,还需要调用IsEqual函数。而如果我们使用赋值运算符重载时,我们可以在外部定义(成员变量必须为public作用域)
             
        我们在比较两个类对象大小时,就不用自己调用了,系统会为我们调用。这就是使用运算符重载的目的:自己设置规则,告诉编译器,自定义对象遇到该运算符时应该如何操作。
在编写运算符重载时,我们应该注意:
1.不能通过连接其他符号来创建新的操作符,比如operator@
2.重载操作符必须有一个类类型或者枚举类型的操作数(否则会出现无限递归),举个例子:

3.用于内置类型的操作符,其含义不能改变,例如:
               
我们在使用时就会出现,a-b—> a+b,而且在调试时很难发现(这样的错误很难在调试时被关注)。
4.作为类成员的重载函数时,其形参看起来比操作数数目少1成员函数(操作符有一个默认形参this,限定为第一个形参),按上述类举例,内置重载函数可以变为:

5.C++中有很多运算符,其中这五个运算符不能重载:.*    ::      sizeof      ?:  .    这五个比较典型。
接下来我们再看,正常的我们可以将a=b=c做到连续赋值,但是当我们想让类的对象进行这样的简单赋值却不可以:

会出现报错,那么我们该怎么进行这类赋值呢?
上述我们写的赋值运算符肯定是不行的,上述其实是将d1赋值给d2,这时类型就变成了viod,再给Date d3赋值时,类型就不一样了。
所以,我们修改赋值运算符重载,让它符合我们的要求:
               
        所以,以自定义类型作为函数的参数,尽量传递引用,因为在传参时,不需要拷贝临时对象;如果不想通过形参修改外部实参,最好给形参加const—参考之前讲过的拷贝构造函数参数。如果自定义类型作为函数的返回值类型时,能引用的尽可能引用,这样可以增加效率。
接下来我们再来看一个特殊的赋值运算符重载:前置++和后置++

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



    推荐阅读