1. 类和对象进阶:初始化列表与static成员
在C++面向对象编程中,初始化列表和static成员是两个经常被初学者忽视但极其重要的特性。让我们先从一个实际案例开始:假设我们需要设计一个3D游戏引擎中的Vector3类,这个类需要高效地初始化三个坐标值,并且需要统计当前场景中所有Vector3实例的数量。
1.1 为什么需要初始化列表
传统的构造函数内赋值方式是这样的:
cpp复制class Vector3 {
public:
Vector3(float x, float y, float z) {
m_x = x;
m_y = y;
m_z = z; // 这是在赋值而非初始化
}
private:
float m_x, m_y, m_z;
};
这种方式看似合理,但实际上存在效率问题。因为成员变量在进入构造函数体之前就已经被默认初始化了,构造函数内的操作实际上是二次赋值。对于简单类型如float可能影响不大,但对于复杂类型(如含有动态内存分配的类),这意味着不必要的构造+拷贝开销。
初始化列表的写法更高效:
cpp复制Vector3(float x, float y, float z) : m_x(x), m_y(y), m_z(z) {}
这里有几个关键点需要注意:
- 初始化顺序由成员变量的声明顺序决定,与初始化列表中的顺序无关
- const成员和引用成员必须使用初始化列表
- 对于没有默认构造函数的成员类对象,也必须使用初始化列表
提示:养成总是使用初始化列表的习惯,即使对于基本类型。这能让代码更一致,也避免潜在的性能损失。
1.2 static成员的妙用
继续我们的Vector3例子,假设我们需要统计场景中所有向量的数量。static成员就是为此而生的:
cpp复制class Vector3 {
public:
Vector3(float x, float y, float z) : m_x(x), m_y(y), m_z(z) {
++s_count; // 每次构造时计数增加
}
~Vector3() {
--s_coun
