一、什么是初始化列表在C中构造函数用于初始化对象。但你有没有想过成员变量到底是在哪里完成初始化的是在构造函数的大括号内部还是在冒号后面今天我们就来深入探讨构造函数的初始化列表——这个常常被初学者忽略却至关重要的语法。初始化列表是构造函数的一种特殊语法写在函数参数列表之后、函数体之前以冒号:开头后面列出成员变量的初始化方式。classStudent{public:// 初始化列表name和score在进入函数体之前就完成了初始化Student(string n,ints):name(n),score(s){// 函数体可做额外操作}private:string name;intscore;};一般认为初始化列表是每个成员变量定义初始化的地方。二、为什么需要初始化列表1. 效率更高对于类类型的成员使用初始化列表是直接初始化而在函数体内赋值是先默认构造再赋值多了一次函数调用。classTest{public:Test(){cout默认构造endl;}Test(intx){cout带参构造endl;}Testoperator(intx){cout赋值endl;return*this;}};classDemo{Test t;public:// 初始化列表一次带参构造Demo(intx):t(x){}// 函数体内赋值先默认构造再赋值Demo(intx){tx;// 先调用Test()再调用operator}};结论对于类类型成员初始化列表更高效。2. 有些成员只能在初始化列表中初始化以下四种成员必须使用初始化列表不可改变所以必须在定义时就赋初值不能在构造函数体内赋值(1) const成员变量classConstDemo{constintci;public:ConstDemo(intx):ci(x){}// 正确// ConstDemo(int x) { ci x; } // 错误const不能赋值};(2) 引用成员变量classRefDemo{intref;public:RefDemo(intr):ref(r){}// 正确// RefDemo(int r) { ref r; } // 错误引用必须初始化};(3) 成员对象没有默认构造函数classMember{public:Member(intx){}// 有带参构造没有默认构造};classContainer{Member m;public:// 必须在初始化列表中调用Member的带参构造Container(intx):m(x){}};(4) 基类没有默认构造函数classBase{public:Base(intx){}};classDerived:publicBase{public:// 必须在初始化列表中显式调用基类构造Derived(intx):Base(x){}};三、初始化列表的语法类名(参数列表) :成员1(值1),成员2(值2),… ,成员n(值n) {// 函数体}多个成员用逗号分隔可以混合使用初始化列表和函数体赋值初始化列表在函数体执行之前执行示例classPoint{intx,y;public:Point(inta,intb):x(a),y(b){coutPoint构造完成endl;}};四、初始化顺序成员变量的初始化顺序由它们在类中声明的顺序决定与初始化列表中的书写顺序无关。classDemo{inta;intb;public:// 易错写法想先用b初始化a但实际a先初始化Demo(intx):b(x),a(b){}// a先初始化此时b未初始化a是随机值};五、初始化列表 vs 函数体赋值对比维度初始化列表函数体内赋值执行时机对象成员内存分配后立即执行进入函数体后执行对const/引用✅ 支持❌ 不支持效率类类型直接构造一次操作先默认构造再赋值两次操作代码风格更专业推荐可用于简单类型或需要额外逻辑的场合七、完整示例#includeiostream#includestringusingnamespacestd;classCourse{public:Course(string n):name(n){cout课程《name》已创建endl;}private:string name;};classStudent{private:constintid;// const成员stringmentor;// 引用成员Course c;// 对象成员Course无默认构造intscore;// 普通成员public:// 初始化列表处理所有必须成员Student(inti,stringm,string courseName,ints):id(i),mentor(m),c(courseName),score(s){cout学生id注册成功endl;}voidshow(){cout学号id导师mentor成绩scoreendl;}};intmain(){string mentorName张教授;Studentstu(1001,mentorName,C程序设计,95);stu.show();return0;}输出text课程《C程序设计》已创建学生1001注册成功学号1001导师张教授成绩95六、补充C11支持在成员变量声明的位置给缺省值用以给没有显示在初始化列表初始化的成员使用所有成员都会走初始化列表哪怕是没有写在初始化列表中的成员。所以我们尽量用初始化列表进行初始化。无论是否显示写初始化列表每个构造函数都有初始化列表。
C++:初始化列表
发布时间:2026/6/10 19:58:38
一、什么是初始化列表在C中构造函数用于初始化对象。但你有没有想过成员变量到底是在哪里完成初始化的是在构造函数的大括号内部还是在冒号后面今天我们就来深入探讨构造函数的初始化列表——这个常常被初学者忽略却至关重要的语法。初始化列表是构造函数的一种特殊语法写在函数参数列表之后、函数体之前以冒号:开头后面列出成员变量的初始化方式。classStudent{public:// 初始化列表name和score在进入函数体之前就完成了初始化Student(string n,ints):name(n),score(s){// 函数体可做额外操作}private:string name;intscore;};一般认为初始化列表是每个成员变量定义初始化的地方。二、为什么需要初始化列表1. 效率更高对于类类型的成员使用初始化列表是直接初始化而在函数体内赋值是先默认构造再赋值多了一次函数调用。classTest{public:Test(){cout默认构造endl;}Test(intx){cout带参构造endl;}Testoperator(intx){cout赋值endl;return*this;}};classDemo{Test t;public:// 初始化列表一次带参构造Demo(intx):t(x){}// 函数体内赋值先默认构造再赋值Demo(intx){tx;// 先调用Test()再调用operator}};结论对于类类型成员初始化列表更高效。2. 有些成员只能在初始化列表中初始化以下四种成员必须使用初始化列表不可改变所以必须在定义时就赋初值不能在构造函数体内赋值(1) const成员变量classConstDemo{constintci;public:ConstDemo(intx):ci(x){}// 正确// ConstDemo(int x) { ci x; } // 错误const不能赋值};(2) 引用成员变量classRefDemo{intref;public:RefDemo(intr):ref(r){}// 正确// RefDemo(int r) { ref r; } // 错误引用必须初始化};(3) 成员对象没有默认构造函数classMember{public:Member(intx){}// 有带参构造没有默认构造};classContainer{Member m;public:// 必须在初始化列表中调用Member的带参构造Container(intx):m(x){}};(4) 基类没有默认构造函数classBase{public:Base(intx){}};classDerived:publicBase{public:// 必须在初始化列表中显式调用基类构造Derived(intx):Base(x){}};三、初始化列表的语法类名(参数列表) :成员1(值1),成员2(值2),… ,成员n(值n) {// 函数体}多个成员用逗号分隔可以混合使用初始化列表和函数体赋值初始化列表在函数体执行之前执行示例classPoint{intx,y;public:Point(inta,intb):x(a),y(b){coutPoint构造完成endl;}};四、初始化顺序成员变量的初始化顺序由它们在类中声明的顺序决定与初始化列表中的书写顺序无关。classDemo{inta;intb;public:// 易错写法想先用b初始化a但实际a先初始化Demo(intx):b(x),a(b){}// a先初始化此时b未初始化a是随机值};五、初始化列表 vs 函数体赋值对比维度初始化列表函数体内赋值执行时机对象成员内存分配后立即执行进入函数体后执行对const/引用✅ 支持❌ 不支持效率类类型直接构造一次操作先默认构造再赋值两次操作代码风格更专业推荐可用于简单类型或需要额外逻辑的场合七、完整示例#includeiostream#includestringusingnamespacestd;classCourse{public:Course(string n):name(n){cout课程《name》已创建endl;}private:string name;};classStudent{private:constintid;// const成员stringmentor;// 引用成员Course c;// 对象成员Course无默认构造intscore;// 普通成员public:// 初始化列表处理所有必须成员Student(inti,stringm,string courseName,ints):id(i),mentor(m),c(courseName),score(s){cout学生id注册成功endl;}voidshow(){cout学号id导师mentor成绩scoreendl;}};intmain(){string mentorName张教授;Studentstu(1001,mentorName,C程序设计,95);stu.show();return0;}输出text课程《C程序设计》已创建学生1001注册成功学号1001导师张教授成绩95六、补充C11支持在成员变量声明的位置给缺省值用以给没有显示在初始化列表初始化的成员使用所有成员都会走初始化列表哪怕是没有写在初始化列表中的成员。所以我们尽量用初始化列表进行初始化。无论是否显示写初始化列表每个构造函数都有初始化列表。