文章目录
- 一、流插入流提取
- 1、流插入演示
- 2、流提取演示
- 3、cplusplus推荐
- 二、const成员
- 三、取地址及const取地址操作符重载
- 四、再谈构造函数
- 1、构造函数体赋值
- 2、初始化列表
- 3、explicit关键字
一、流插入流提取
1、流插入演示
这里我们可能有个问题,之前我们知道流插入流提取可以自动识别类型,但为什么识别不了自定义类型呢?
打开Cplusplus.com
我们可以清楚的看到大部分内置类型已经存在库中,相当于去调用库中的函数,所以可以自动识别类型,而自定义类型没有存在库中,需要我们手写。
我们可以看出来上图没法通过,下图可以通过为什么呢?这里是因为,d1<<cout从左往右,第一个必须对应this指针,所以我们可以将这个函数定义在外面。
下午虽然可以打印,但是我们总看别别扭。
我们定义在了外面,可是成员对象又是私有的,设成公有的又不太好,这里我们涉及涉及友元概念。
我们可以看出来这样可以执行。
但是我们又有一个问题,如果想打印多个自定义类型,又该怎么做呢?
我们可以这样做。返回类型设为流插入返回,这样可以很好解决问题
2、流提取演示
3、cplusplus推荐
新版的cplusplus有出现短路,这里我们可以使用旧版的。
二、const成员
将const修饰的“成员函数”称之为const成员函数,const修饰类成员函数,实际修饰该成员函数隐含的this指针,表明在该成员函数中不能对类的任何成员进行修改。
我们来看看下面的代码
请思考下面的几个问题:
- const对象可以调用非const成员函数吗?
- 非const对象可以调用const成员函数吗?
我们通过上述代码来解答
1、不能
2、可以
三、取地址及const取地址操作符重载
这两个默认成员函数一般不用重新定义 ,编译器默认会生成。
这两个运算符一般不需要重载,使用编译器生成的默认取地址的重载即可,只有特殊情况,才需要重载,比如想让别人获取到指定的内容!
如:
至于下图为什么,不是空呢?原因在于&d2不会去调用非const函数,他会去调用它的默认函数。
四、再谈构造函数
1、构造函数体赋值
在创建对象时,编译器通过调用构造函数,给对象中各个成员变量一个合适的初始值。
虽然上述构造函数调用之后,对象中已经有了一个初始值,但是不能将其称为对对象中成员变量的初始化,构造函数体中的语句只能将其称为赋初值,而不能称作初始化。因为初始化只能初始化一次,而构造函数体内可以多次赋值。
2、初始化列表
初始化列表:以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个"成员变量"后面跟一个放在括号中的初始值或表达式。
注意:
- 每个成员变量在初始化列表中只能出现一次(初始化只能初始化一次)
- 类中包含以下成员,必须放在初始化列表位置进行初始化:
引用成员变量
const成员变量
自定义类型成员(且该类没有默认构造函数时)
我们知道引用的时候必须初始化,const只能初始化一次,所以这些必须放在初始化列表中
3.尽量使用初始化列表初始化,因为不管你是否使用初始化列表,对于自定义类型成员变量,一定会先使用初始化列表初始化。
4.成员变量在类中声明次序就是其在初始化列表中的初始化顺序,与其在初始化列表中的先后次序无关
我们可以看出答案选D 为什么呢?
因为我们先声明_a2所以我们先初始化a2,在初始化_a1。
3、explicit关键字
构造函数不仅可以构造与初始化对象,对于单个参数或者除第一个参数无默认值其余均有默认值的构造函数,还具有类型转换的作用。
我们可以看出下图代码可以实现
但是当我们加上explicit关键字后,就不支持隐式转换了,但是支持强制类型转换