本文共 1673 字,大约阅读时间需要 5 分钟。
7.5 构造函数再探
7.5.1 构造函数初始值列表
1、成员的赋值不等于成员的初始化,成员的赋值为先进行初始化再赋值
2、如果成员是const、引用、或者属于某种未提供默认构造函数的类类型,必须通过构造函数初始值列表为成员提供初值
3、初始化效率高于赋值,建议使用初始化列表
4、初始化列表成员的初始化顺序和成员在类中定义的顺序相同,建议将构造函数初始化列表中的成员的顺序和成员定义的顺序相同,且尽量避免使用成员1初始化成员2
5、没有出现在构造函数初始化列表中的成员将通过相应的类内初始值(如果存在的话)初始化,或者执行默认初始化
7.5.2 委托构造函数
1、一个委托构造函数使用它所属类的其他构造函数执行它自己的初始化过程,或者说它把它自己的一些(或者全部)职责委托给了其他构造函数
class Sales_data {public: //非委托构造函数使用对应的实参初始化成员 Sales_data(std::string s, unsigned int, double price): bookNo(s), units_sole(cnt), revenue(cnt*price) {} //其余构造函数全部委托给另一个构造函数 Sales_data():Sale_data("", 0, 0) {} Sales_data(std::string s):Sales_data(s, 0, 0) {} Sales_data(std::stream &is):Sales_data() {read(is, *this)}]
当一个构造函数委托给另一个构造函数时,受委托的构造函数的初始化列表和函数体被依次执行,执行完后控制权才会交给委托者的函数体。
7.5.3 默认构造函数的作用
1、当对象被默认初始化或者值初始化时自动执行默认构造函数(即不含有任何参数的构造函数)。
默认初始化在以下情况发生:
- 在块作用域中不使用任何初始值定义一个非静态变量或者数组时
- 当一个类本身还有类类型的成员且该成员的类型使用合成的默认构造函数时
- 当类类型的成员没有在构造函数初始值列表中显示的初始化时
值初始化在以下情况发生
- 数组初始化时提供的初始值少于数组的大小时
- 不使用初始值定义一个局部静态变量时
- 使用T()的表达式显示地请求值初始化时,其中T是类型名
2、在实际使用中,如果定义了其他构造函数,最好也定义一个默认构造函数,假如有内置类型成员,可以定义类内初始值,假如编译器不支持类内初始值,则默认构造器可以使用初始化列表初始化内置类型成员
3、合成的默认构造函数初始化规则
- 如果存在类内初始值,则用它来初始化成员
- 否则默认初始化该成员
4、某些类不能依赖于合成的默认构造函数
- 只有当类没有声明任何构造函数时,编译器才会自动合成默认构造函数
- 如果类包含有内置类型或者复合类型(数组和指针)的成员时,则只有当这些成员全都被赋予了类内初始值时,这个类才适合于使用合成的默认构造函数,否则其初始值是为定义的(类似于定义在块内的内置类型或复合类型的初始值被默认初始化时是未定义的)
- 有的时候编译器不能为某些类合成默认的构造函数。例如类中包含一个其他类类型的成员且这个成员的类型没有默认构造函数,那么编译器无法初始化该成员,对于这样的类我们必须自己定义默认构造函数,否则该类没有默认的构造函数
5、如果定义一个使用默认构造函数进行初始化的对象,正确的方法是去掉对象后面的空的括号对
Sales_data obj;
7.5.4 隐式的类型转换
1、编译器只允许一步类型转换
2、类内声明构造函数时使用explicit关键字抑制构造函数定义的隐式转换,explicit在类外部定义时不应重复
3、explicit构造函数只能用于直接初始化,即不允许使用拷贝形式的初始化(使用=)
Sales_data item1(null_book);Sales_data item2 = null_book; //error
转载地址:https://blog.csdn.net/RachleMa/article/details/117339749 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!