初始化列表
在C++中,初始化列表是一种在构造函数中为成员变量赋初值的语法,它能够提高代码执行效率并且适用于各种类型的成员变量初始化。初始化列表使用冒号(:)来开始,然后在冒号后面的花括号内对成员变量进行初始化。以下是一个示例:
class MyClass {
private:
int num;
double value;
public:
MyClass(int n, double v) : num(n), value(v) {
// 构造函数体
}
};
在上面的示例中,构造函数MyClass(int n, double v)使用初始化列表来初始化成员变量num和value。通过num(n)和value(v),将参数n赋值给成员变量num,将参数v赋值给成员变量value。
使用初始化列表有几个优势:
- 提高执行效率,避免了先调用默认构造函数再进行赋值的过程,直接在对象创建时就完成了初始化,减少了不必要的中间步骤,提高了代码执行效率;
- 适用于const成员变量和引用类型,它们在创建后不能再被修改,因此必须在对象创建时进行初始化。使用初始化列表可以满足这一需求;
- 初始化数组成员,如果类中有数组类型的成员变量,使用初始化列表可以方便地对数组进行初始化,避免了在构造函数体内逐个元素进行赋值的麻烦;
- 初始化其他类对象,如果类中有其他类对象作为成员变量,使用初始化列表可以直接调用相应的构造函数进行初始化,代码更加简洁清晰。
除了上述提到的优势,初始化列表还可以应用于对象的复制构造、继承关系中的构造函数以及成员对象的初始化顺序等场景。使用初始化列表可以使代码更加简洁清晰,提高程序的可读性和可维护性。
下面给出一个具体的代码示例来演示初始化列表的使用:
#include<iostream>
using namespace std;
class A
{
public:
A(int a = 0)
: _a(a)
{
cout << "A(int a = 0)" << endl;
}
private:
int _a;
};
class Date
{
public:
Date(int year, int month, int day)
: _ref(year)
, _n(1)
, _aa(10) // 能不能只用初始化列表?
// 不能,因为有些初始化或者检查的工作,
// 初始化列表不能完全搞定。
{
//函数主体初始化
_year = year;
_month = month;
_day = day;
}
void print()const
{
cout << _year << "/" << _month << "/" << _day << endl;
}
private:
int _year = 1; // 如果这里写缺省值,这个缺省值是给初始化列表的
int _month;
int _day;
A _aa; // 有些自定义成员想要显式初始化
// 没有默认构造的自定义成员
int& _ref; //引用: 必须在定义的时候初始化
const int _n; //const: 必须在定义的时候初始化(只有一次初始化的机会)
};
int main()
{
// 定义对象的整体定义
// 每个成员变量在什么地方定义?在初始化列表
Date d1(2023, 11, 3);
d1.print();
return 0;
}
在上面的示例中,类Date使用了初始化列表来初始化其成员变量。其中,_ref和_n是引用和const类型,必须在定义的时候进行初始化,使用了初始化列表将其初始化;同时,_aa是一个自定义类类型,也使用了初始化列表进行初始化。
注意:
- 每个成员变量在初始化化列表中只能出现一次(初始化只能初始化一次)
- 类中包含以下成员,必须放在初始化列表位置初始化化:
- 引用成员变量
- const成员变量
- 自定义类型成员
- 尽量使用初始化列表初始化,因为不管你是否使用初始化列表,对于自定义类型成员变量,一定会先使用初始化列表初始化。
- 成员变量在类中声明次序就是其在初始化列表中的初始化顺序,与其在初始化列表中的先后 次序无关
- 举例:
class A
{
public:
A(int a)
:_a1(a)
,_a2(_a1)
{}
void Print() {
cout<<_a1<<" "<<_a2<<endl;
}
private:
int _a2; //初始化的顺序是按声明的顺序走的!
int _a1;
};
int main() {
A aa(1);
aa.Print();
}
A. 输出1 1
B.程序崩溃
C.编译不通过
D.输出1 随机值

答案是D
1047

被折叠的 条评论
为什么被折叠?



