C++构造函数的初始化列表
在 C++ 中,构造函数负责初始化新创建的对象。然而,除了构造函数体中的赋值操作,C++ 还提供了一种更高效、更精确的方式来初始化成员变量,叫做初始化列表。
初始化列表紧跟在构造函数参数列表的后面,以一个冒号开头,然后是成员变量及其初始值,初始值用圆括号包裹着。例如,MyClass 类的构造函数以初始化列表的方式为各个成员变量赋初值:
搞清楚以上两种初始化方式的区别之后,如果类中有 const 或引用类型的成员变量,必须使用初始化列表来初始化它们,因为这些类型的成员变量在创建后就不能更改。
例如:
使用初始化列表时,有一些需要注意的地方:
初始化列表紧跟在构造函数参数列表的后面,以一个冒号开头,然后是成员变量及其初始值,初始值用圆括号包裹着。例如,MyClass 类的构造函数以初始化列表的方式为各个成员变量赋初值:
class MyClass {
public:
MyClass(int a, double b) : m_a(a), m_b(b) {} // 初始化列表
private:
int m_a;
double m_b;
};
在 C++ 中,构造函数的初始化列表是非常有用的,这点让初学者非常疑惑,因为下面的语句也能达到同样的目的,且更加直观:
MyClass(int a, double b){
m_a = a;
m_b = b;
}
上面两种方法是有区别的,初始化列表的方式对每个变量只有一次初始化,而后一种方法则先用默认值初始化,然后再赋相应的值,也就是说在进入构造函数之前已经完成了初始化。因此,使用初始化列表的效率更高。搞清楚以上两种初始化方式的区别之后,如果类中有 const 或引用类型的成员变量,必须使用初始化列表来初始化它们,因为这些类型的成员变量在创建后就不能更改。
例如:
class MyClass {
public:
MyClass(int a, const std::string& s) : m_a(a), m_s(s) {}
private:
int m_a;
const std::string m_s; // 必须使用初始化列表
};
初始化列表的完整实例
下面的例子中定义了一个 Point 类,用来表示在三维坐标系统下的一个点,类的构造函数可以接收 3 个参数,或者忽略 z 坐标,或者不提供初始化参数。
#include <iostream>
using namespace std;
class Point
{
friend ostream& operator << (ostream & out, const Point & p); //输出函数
public:
// 3 个参数的构造函数
Point(int x, int y, int z) :m_x(x), m_y(y), m_z(z) {
cout << "3 个参数的构造函数被调用" << *this << endl; //输出数据
}
// 2个参数的构造函数
Point(int x, int y) :m_x(x), m_y(y), m_z(0) {
cout << "2个参数的构造函数被调用" << *this << endl; //输出数据
}
//无参数的构造函数
Point() :m_x(0), m_y(0), m_z(0) {
cout << "无参数的构造函数被调用" << *this << endl;
}
// 复制构造函数
Point(const Point& p) :m_x(p.m_x), m_y(p.m_y), m_z(p.m_z) {
cout << "复制构造函数被调用" << *this << endl; //输出数据
}
private:
int m_x, m_y, m_z;
};
//重载输出操作符
ostream& operator<<(ostream& out, const Point& p)
{
out << "x = " << p.m_x << "y = " << p.m_y << "z = " << p.m_z;
return out;
}
Point fun(Point p)
{
return p;
}
int main(){
Point pl;
Point p2(10, 10);
Point p3(10, 10, 10);
Point p4 = p2;
fun(p3);
}
执行结果为:
无参数的构造函数被调用x = 0 y = 0 z = 0
2个参数的构造函数被调用x = 10 y = 10 z = 0
3 个参数的构造函数被调用x = 10 y = 10 z = 10
复制构造函数被调用x = 10 y = 10 z = 0
复制构造函数被调用x = 10 y = 10 z = 10
复制构造函数被调用x = 10 y = 10 z = 10
总结
构造函数的初始化列表是 C++ 中一种强大而灵活的特性,它不仅提高了代码的执行效率,还为成员变量的精确初始化提供了更多控制。使用初始化列表时,有一些需要注意的地方:
- 不是所有的数据成员都必须出现在初始化列表中;
- 初始化列表中每个成员只能出现一次,不可以重复初始化;
- 数据成员在初始化列表中的出现顺序与类中定义的顺序无关;
- 如果类中有 const 或引用类型的成员变量,必须使用初始化列表来初始化它们。
ICP备案:
公安联网备案: