1.引子
类中,如果有自定义类型,初始化对象时会调用它的默认构造,但如果这个自定义类型没有默认构造,要传参呢?
一.初始化列表
1.定义
类中成员变量初始化的地方(非静态)
2.格式
在构造函数函数头与函数体之间
例:Date(int a)
:year(30)//括号替代赋值符
,month(12)//括号中为要赋值给成员的语句,表达式
,day(a)//注释行为初始化列表
{}//可以在这里面对已经初始化的成员进一步处理
3.理解
类中别的地方对成员函数仅是声明,对象初始化时,每个非静态成员函数都要进初始化列表初始化,没有在里面写赋值的,先找有没有缺省值,没有编译器不一定会处理,可能为随机值。
不论写不写,类中都有初始化列表,不过没有显示传参,可以给缺省值让其初始化。
4.给缺省值
给成员变量缺省值相当于在初始化列表里给值,如果既给了缺省值,又在初始化列表给了值,就会采用初始化列表中的值(给缺省值的由来)。
5.必须在初始化列表初始化的成员(作用)
1.const修饰的成员变量。
因为const变量必须在定义时初始化,所以不能不给它值,它一定会进初始化列表初始化。可以给缺省值或初始化列表给值。
2.引用
同const,引用必须在定义时初始化,且后续不能改,所以如果要让其引用外部变量,必须在初始化列表给值,给缺省值必须能拿到一些对象初始化就有的变量。(如全局,在其之前初始化的成员
变量)
3.自定义类型含参构造的对象
若要调用只能在初始化列表中加括号传参构造,不然初始化列表默认调用默认构造。
不能通过给缺省值来调他的普通构造(给缺省值必须要有赋值符号),拷贝构造可以,前者必须在初始化列表中写。
6.常用
1.成员变量初始化一般放在初始化列表中初始化,自己写的构造函数的函数体中写对变量的进一步处理。
2.初始化列表中括号内可以写表达式语句如:malloc...
7.初始化顺序
按照成员变量声明的顺序初始化。(所以初始化列表中顺序最好与声明顺序相同)
原因:成员对象是按声明顺序在内存中存的
二.隐式转换构造
1.定义
将非对象成员直接通过赋值符号初始化对象
2.前提
对象类中有传参构造
3.用法
1.单传参
直接将值赋给要初始化的对象
2.多传参
将多个值用花括号括起来,逗号分隔,传给要初始化的对象。
4.理解
1.编译器将值隐式类型转化了,期间产生了一个常量性临时变量(编译器自己生成的),用值初始化这个临时变量,再将临时变量通过拷贝构造初始化要初始化的对象(date)。
2.有的编译器会直接优化为将值直接传给要初始化对象的构造。(调试可见)
5.使用
1.在外部可以直接通过值初始化对象(多用),也可以直接传给const修饰的引用。(少用)
(注意:常量型对象与常量引用对象都不能调用其成员函数,只能通过一模一样类型的对象调用)
2.隐式类型转化的值前面可以不写赋值符号。(同加了赋值符号的)(少用)
关键字explicit
在构造函数函数头前加,不允许隐式转化初始化
图中不允许{}内隐式类型转化