C++ 成员初始化列表
- 更高效:少了一次调用默认构造函数的过程。
- 有些场合必须要用初始化列表:
- 常量成员,因为常量只能初始化不能赋值,所以必须放在初始化列表里面
- 引用类型,引用必须在定义的时候初始化,并且不能重新赋值,所以也要写在初始化列表里面
- 没有默认构造函数的类类型,因为使用初始化列表可以不必调用默认构造函数来初始化
成员初始化列表
成员初始化列表是C++中类构造函数的一部分,用于在构造函数体执行之前初始化类的数据成员。它在性能和功能上有显著优势,尤其是对于常量成员或引用成员。
定义
成员初始化列表是指通过在构造函数的冒号 (:
) 后直接列出数据成员及其初始值来初始化成员的语法。它的形式如下:
ClassName(parameters) : member1(value1), member2(value2), ... {
// 构造函数体
}
主要用途
1. 初始化常量成员
常量成员 (const
) 必须在初始化列表中初始化,因为它们只能赋值一次。
#include <iostream>
class Example {
const int value;
public:
Example(int v) : value(v) {} // 使用初始化列表
void show() const { std::cout << "value: " << value << std::endl; }
};
int main() {
Example ex(10);
ex.show();
return 0;
}
输出:
value: 10
2. 初始化引用成员
引用成员必须在初始化列表中初始化,因为引用在创建时必须绑定到对象。
#include <iostream>
class Example {
int &ref;
public:
Example(int &r) : ref(r) {} // 使用初始化列表
void show() const { std::cout << "ref: " << ref << std::endl; }
};
int main() {
int x = 42;
Example ex(x);
ex.show();
return 0;
}
输出:
ref: 42
3. 初始化基类和成员对象
派生类可以通过初始化列表调用基类的构造函数,成员对象也可以通过初始化列表调用其构造函数。
#include <iostream>
class Base {
public:
Base(int x) { std::cout << "Base initialized with " << x << std::endl; }
};
class Derived : public Base {
int value;
public:
Derived(int x, int y) : Base(x), value(y) {
std::cout << "Derived initialized with " << y << std::endl;
}
};
int main() {
Derived d(1, 2);
return 0;
}
输出:
Base initialized with 1
Derived initialized with 2
区别分析
初始化列表 vs 构造函数体赋值
- 性能:初始化列表直接初始化成员,效率更高;构造函数体内赋值是先默认初始化,再赋值,可能引入额外开销。
- 必需性:对于
const
、引用或无默认构造函数的类成员,必须使用初始化列表。
#include <iostream>
class Example {
const int value;
public:
// Example(int v) { value = v; } // 错误:const成员不能在构造函数体中赋值
Example(int v) : value(v) {} // 正确
};
总结:在可能的情况下,优先使用成员初始化列表以提高性能并避免潜在错误。