运算符重载和初始化列表

运算符重载

为了增强程序的可读性

本意就是让对象实例化后也能使用‘+’,‘-’,‘>’,‘

这里就要用到operator关键字

由于这三个变量都是类里面私有的,所以先暂时设置成共有的

如果我们要将结果打印出来,这样写就会报错,这是因为

所以这里代码需要点小小的修改,就会打印出布尔值

我们也可以将operator函数放在类里面,但是编译器说参数太多了

因为成员函数都有一个隐藏参数,所以只需要写一个参数就够了

这五个运算符不能重载

后面几个运算符的实现就可以使用代码复用

赋值运算符的重载

这就是简单的赋值运算符重载的实现

但似乎不能进行连等运算

上面的连等是先d1赋值给d3,赋值后就应该有个返回值,然后用这个返回值给d2赋值,所以我们给运算符重载函数加个返回值就行了,而且出了作用域*this还在,为了避免拷贝构造浪费空间就可以直接使用引用返回

而且还有可能会写出d1=d1这样自己赋值给自己的情况,所以函数还要改一下,将这种情况剔除

这里的两行代码也是拷贝构造;因为赋值重载是两个已经创建出来的的对象进行赋值,但是这里的d5和d6都是新创建然后赋值的,所以说这个是拷贝构造,而不是赋值重载

日期类

这个日期好像有些问题,所以要对构造函数进行修改

再写一个日期加天数的函数

顺便写个加的

还有前置++与后置++

前置++就正常写

后置++为了构成函数重载,就加了个参数

再写一个日期减等天数

再写个日期减天数

但有时会出现这种情况,这说明函数设计还是略有欠缺

修改一下就好了

再写个前置和后置--

再看看两个日期之间的天数的计算

流插入重载

接着我们发现好像实例化后的对象并不能直接使用cout函数,是因为

查官方文档可以知道,cout是ostream类型里面的一个对象

而且ostream是默认支持内置类型的

但是自定义类型却是不支持,需要自己写,但是ostream类是c++库里的不能修改,所以就只能重载

这里的out就是cout的别名,后面就可以直接将out当cout用

但由于调用函数是上面的,那么具体使用就变成了下面的,因为ostream类不能修改,所以就只能写在日期类里面了,但是写在日期类里面的话,日期类对象就抢占了第一个参数,所以cout就只能写在后面了

运算符重载不一定要作为成员函数,而是可以作为一个全局函数,但是就不能访问成员函数里面的私有成员变量

所以我们可以在类里面加一个友元函数,将这个流插入函数变成日期类的友元函数,这样就可以访问私有的成员变量了

这下就可以正常打印了

但是这里的cout好像不支持连续插入,其实这里是多次的函数调用,这里就相当于d1先插入到cout,然后返回cout,再将d2插入到cout中去。

这就是多个函数调用。所以这里的流插入重载就需要写返回值,返回的就是out,out就是cout的别名

流提取重载

当然,这个函数也必须是友元函数

我们也可以将这两个函数写成内联函数,这种短小的函数都可以写成内联函数

初始化列表

可以认为是成员变量定义的地方

默认生成的构造函数对内置类型不作处理,这里的_x成员变量是int类型的,编译器也不会作处理,但是这是个const修饰的变量,const修饰的变量只读不写,必须在定义的位置就初始化

所以必须给每个成员变量找一个定义的位置,不然像const这样的成员不好处理

哪个对象调用构造函数,初始化列表是所有成员变量定义的位置

不管是否显示在初始化列表写,编译器每个变量都会初始化列表定义初始化

就像这段代码,a1初始化列表没有定义,就用的缺省值1,a2初始化列表定义了,那么就是1,随后a1++,a2--,最终的a1是2,a2是0

再看一下这段代码

结果是1和随机值,这是因为成员变量在类中的声明次序就是其在初始化列表中的初始化顺序,与其在初始化列表中的先后次序无关

必须要在初始化列表中的定义的三种情况

1、const修饰的变量

2、引用

3、没有默认构造的自定义类型成员

看这一段代码,类A的构造函数是个单参数的

aa1是属于调用构造函数

而aa2则是类型转换,是一种隐式类型转换,是内置类型和自定义类型之间的转换

这里有一个内置类型之间的转换

i并不是直接转换成a的,而是会产生一个double类型的临时变量,i的值赋给临时变量,再由临时变量赋值给a。这个临时变量具有常性

这个类型转换也是一样的,也会创建一个临时变量;先用1去构造一个A的临时对象,再进行拷贝构造

现在验证一下,按刚才的分析打印的结果应该是两个构造一个拷贝构造

但结果只有两个构造

原来C++针对自定义类型产生临时变量的这种情况会进行优化

所以将构造+拷贝构造优化成了直接构造

再看看这个,ref不能引用这个10

但const修饰后就可以了,这恰恰证明了这个10产生了临时对象

如果在构造函数前面加上关键字 explicit 就不能进行隐式类型转换了

如果是多参数的构造函数,则是需要加大括号进行隐式类型转换的 加 explicit也同理

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值