
目录1. 含义 和 基本语法2. 为什么使用初始化列表2.1 使用初始化列表效率更高2.2 有些成员必须使用初始化列表3.初始化顺序4. 给缺省值初始化5. 与在函数体内赋值的区别1. 含义 和 基本语法含义之前学过的构造函数初始化是以在函数体内赋值的方式初始化的而初始化列表是构造函数的一部分用于在创建对象时直接初始化成员变量而不是先在函数体内赋值。语法class A { int x; const int y; int r; public: A(int a, int b, int ref) : x(a), y(b), r(ref) { // 函数体 } };冒号:后面是初始化列表。每个成员用 成员名值或 成员名 {值}C11表示。多个成员用逗号分隔。2. 为什么使用初始化列表2.1 使用初始化列表效率更高首先要知道C规定一个对象在真正进入构造函数的大括号{}之前它的所有成员变量都已经完成了 初始化。在函数体内赋值class Date { public: // 函数体内赋值的方式初始化 Date(int year,int month,int day) { _year year; _month month; _day day; } private: int _year; int _month; int _day; };初始化阶段进入大括号前编译器先给_year和_month分配内存。由于没在初始化列表里写编译器会执行默认初始化。对于内置类型int就是随便填个随机垃圾值比如_year现在是乱码。赋值阶段进入大括号后执行_year year;把参数的值赋给原本已是垃圾值的_year。使用初始化列表class Date { public: // 初始化列表初始化 Date(int year, int month, int day) :_year(year), _month(month), _day(day) {} private: int _year; int _month; int _day; };初始化阶段进入大括号前编译器分配内存的同时直接用参数year来构造_year。一步到位没有垃圾值也没有后续的赋值操作。效率差距在哪里对于 内置类型赋值和初始化效率一样就是改内存。但如果成员变量是自定义类型差别就巨大了假设类里有个成员对象对它赋值初始化会先调用它的默认构造进入大括号后再调用赋值运算符重载。一共经历了两次函数调用。而用初始化列表初始化直接调用它的拷贝构造函数。只有一次函数调用效率更高。2.2 有些成员必须使用初始化列表const 成员因为不能在函数体内赋值初始化所以只能只能用初始化列表初始化引用必须在定义时绑定不能重新绑定没有默认构造的类因为对类进行初始化时会调用它的默认构造如果它没有默认构造就会报错所以没有默认构造的类必须用初始化列表初始化3.初始化顺序成员初始化顺序由它们在类中声明的顺序决定与初始化列表中的书写顺序无关。如下4. 给缺省值初始化可以在声明成员时直接给默认值class A { int x 0; int y 1; public: A(int a) : x(a) {} // y 仍使用默认值 1 };如果成员在初始化列表中也被指定则缺省值被忽略比如上面代码中x在初始化列表被初始化缺省值被忽略。5. 与在函数体内赋值的区别方式过程适用性初始化列表直接调用构造函数/初始化所有成员包括 const、引用、无默认构造的类类型函数体内赋值先默认构造再调用赋值运算符仅适用于可默认构造且可赋值的成员