在C++中,类的初始化列表是一个在构造函数体之前用来初始化类成员的机制。它允许你在构造函数的声明部分直接初始化成员变量,而不是在构造函数体内通过赋值的方式。
初始化列表紧跟在构造函数名称之后,用冒号 :
开始,后面跟着成员变量的初始化。每个成员变量通过逗号 ,
分隔。
class ClassName {
public:
// 构造函数带有初始化列表
ClassName(int a, int b) : x(a), y(b) { // x和y分别通过初始化列表初始化
// 其他构造函数体代码(如果有)
}
private:
int x, y;
};
其中x(a)
的意思并不是调用名叫x的函数,而是把成员变量x的值初始化a的值。同样,y(b)
的意思也并不是调用名叫y的函数,而是把成员变量y的值初始化为b的值。
#include
using namespace std;
class Rectangle {
public:
// 带有初始化列表的构造函数
Rectangle(int l, int w) : length(l), width(w) {
// 构造函数体
cout << "Rectangle created!" << endl;
}
// 打印矩形的面积
void area() {
cout << "Area: " << length * width << endl;
}
private:
int length, width;
};
int main() {
Rectangle rect(10, 5); // 创建一个长为10,宽为5的矩形
rect.area(); // 打印矩形的面积
return 0;
}
关键点:
Rectangle(int l, int w) : length(l), width(w)
:初始化列表在这里将 length
和 width
直接初始化为传入的 l
和 w
参数的值。length
和 width
是在构造函数体内使用之前就已经初始化了,而不是在函数体内通过赋值。:
开始,直接在构造函数声明中初始化成员变量。初始化列表(Initializer List)是写在构造函数的函数体 {}
之前,用于初始化成员变量和基类。它的语法如下:
ClassName::ClassName(参数列表) : 成员变量1(值1), 成员变量2(值2), 基类(值) {
// 构造函数体
}
class Example {
int a;
double b;
public:
Example(int x, double y) // 构造函数
: a(x), b(y) // ✅ 初始化列表(在函数体 `{}` 之前)
{
// 构造函数体
}
};
: a(x), b(y)
是 初始化列表,用来初始化 a
和 b
。其中 a(x)
的意思并不是调用名叫a的函数,而是把成员变量a的值初始化x的值。同样,b(y)
的意思也并不是调用名叫b的函数,而是把成员变量b的值初始化为y的值。
{}
内是构造函数体,在初始化列表执行完之后才会运行。
#include
class Base {
public:
Base(int x) { std::cout << "Base constructor: " << x << "\n"; }
};
class Derived : public Base {
int a;
public:
Derived(int x, int y)
: Base(x), a(y) // ✅ 初始化列表
{
std::cout << "Derived constructor: " << a << "\n";
}
};
int main() {
Derived d(10, 20);
}
Base constructor: 10
Derived constructor: 20
流程
Base(x)
先调用 Base
的构造函数,输出 "Base constructor: 10"
。a(y)
赋值给成员变量 a
,即把y的值传递给成员变量a,注意这里不是调用函数名为a的函数。{}
"Derived constructor: 20"
。上面代码中类Derived在定义时继续了基类Base,那么请问public Base
中public的意思是什么?
答案见:https://blog.csdn.net/wenhao_ir/article/details/145428506
class Example {
int x;
public:
Example(int value) : x(value) {} // ✅ 直接初始化
};
class Example {
int x;
public:
Example(int value) { x = value; } // 在构造函数中赋值,不推荐
};
✅ 推荐使用初始化列表,避免在构造函数中赋值,从而提高效率。
由于C++规定,所有成员变量必须在对象构造完成前初始化。而常量成员在初始化后不能修改,所以只能用初始化列表进行初始化。例子如下:
class Test {
const int x;
public:
Test(int val) : x(val) {} // 常量成员x必须用初始化列表进行初始化,否则编译错误
};
关于引用成员为什么也必须在初始化列表中进行初始化,详情见 https://blog.csdn.net/wenhao_ir/article/details/145422877
其实原因也和常量成员差不多,只是你需要了解下C++的引用成员是怎么回事儿。
例子如下:
class Test {
int& ref; // ref是一个引用类型的成员
public:
Test(int& r) : ref(r) {} // ref必须用初始化列表进行初始化
};
如果某个成员变量的类型为类类型,即这个成员变量是一个类的对象实例,而这个类又没有默认构造函数,那么也需要在初始化列表中进行初始化。
详情见 https://blog.csdn.net/wenhao_ir/article/details/145428240
如果一个类的基类没有使用默认构造函数,也需要在初始化列表进行初始化。详情请请看我的另一篇博文 https://blog.csdn.net/wenhao_ir/article/details/145428240