初始化与赋值
两者的区别主要存在于构造函数中,对于内置类型来说,使用初始化列表进行初始化和赋值没有太大的区别,但是对于非内置类型,采用赋值可能会造成错误
当用户自己定义了构造函数,又在新的类中使用了这个类,会造成编译器无法合成默认构造函数,会造成赋值的错误,最好的办法就是使用初始化列表,这实际是调用了默认拷贝函数(不受默认构造函数的影响)
尤其对于引用,const来说,他们不可以被赋值,只能使用初始化列表进行初始化

成员初始化顺序
按照成员在类中定义的顺序进行初始化,而不是按照初始化列表的顺序,不过最好使列表和定义的顺序一致

委托构造函数
本质还是定义构造函数,只是其初始化和实现交给了其他构造函数来完成
格式为构造函数名加冒号建立初始化列表,初始化列表里只有一个通道就是其他的构造函数,最后是花括号
委托构造甚至可以接续委托,比如定义一个委托到默认构造函数,默认构造也是委托,再委托到有参构造

默认构造函数的作用
当对象进行默认初始化和值初始化时进行调用默认构造函数
默认初始化:
(1)块作用域不给初始值定义非静态对象
(2)类内的类类型成员使用合成默认构造
(3)类类型成员没有在初始化列表中初始化
值初始化:
(1)给数组的初始值不够
(2)定义局部静态变量不给初始化值
(3)使用T()请求值初始化
(练习7.43,7.46)

隐式的类类型转换
若构造函数只接受一种实参,则它实际上定义了一种转换为此类型的类型转换机制,有时称这种构造函数为转换构造函数
编译器隐式的将形参类型转换成了类类型,并且可以进行调用,编译器会生成临时类对象来满足调用

只允许一步类类型转换
编译器最后帮助完成一次的隐式类型转换,次数过多就会报错

使用explicit
只对有一个实参的构造函数生效,但是多个实参的构造函数本就不支持隐式转换,多个实参只能声明explicit不能定义
explicit可以禁用隐式类型转换,并且使用explicit声明的构造函数,只能进行直接初始化

一些标准库含有单参数构造函数的类
(1)接受const char*的string类不是explicit
(2)接受容量的vector类是explicit
(练习7.49)

聚合类
聚合类满足以下条件:
(1)所有成员都是public
(2)没有定义任何构造函数
(3)没有类内初始值
(4)没有基类和virtual
可以使用等于和把初始值用花括号括起来的方法(类似赋值)对聚合类的对象初始化,初始值的顺序必须和声明的顺序一致
如果初始化列表的元素不足,会执行值初始化

字面值常量类
可以成为字面值类型的有算术类型、引用、指针和某些类
字面值常量类满足以下条件:
(1)是聚合类,且数据成员都是字面值
(2)数据成员是字面值,类内有constexpr构造函数,若成员有·类内初始值则内置类型成员的的初始值必须是常量表达式,属于某个类的成员初始值必须使用成员自己的constexpr构造函数,类要用默认析构函数
constexpr构造函数一般等于default,或者函数体为空,且constexpr构造函数要初始化所有数据成员,要么给常量表达式,要么给constexpr