在C++的早期版本中,类的成员在构造函数内部通过赋值进行初始化。后来,出现了通过初始化列表在进入构造函数主体之前初始化类成员的能力,这对于常量成员、引用和性能来说是至关重要的。
某些类成员(例如,const字段或引用)不能在构造函数主体内通过赋值进行初始化——它们必须在创建时进行设置。此外,如果使用赋值,首先会调用默认构造函数,然后再进行赋值(两个操作),这对于复杂对象可能是开销较大的:
class Example { const int x; std::string str; public: Example(int val, const std::string& s) : x(val), str(s) {} };
使用初始化列表立即初始化类成员。这对于const、引用、没有默认构造函数的成员类,以及在处理STL类和大型结构时的性能尤其重要。
代码示例:
class Point { const int x; int& y; public: Point(int val, int& ref) : x(val), y(ref) {} };
关键特性:
是否可以通过构造函数初始化列表中的顺序改变类成员的初始化顺序?
不能!成员总是按它们在类中声明的顺序进行初始化,而不是按初始化列表中的顺序。忽视这一规则会导致初始化顺序错误。
如果引用成员在初始化列表中未被初始化,而仅在构造函数体内进行初始化,会发生什么?
编译错误!引用和const字段一样,只能在初始化列表中进行初始化——它们必须在进入构造函数主体之前获得值。
在初始化列表中初始化const成员后,可以在构造函数体内修改它吗?
不可以,常量成员在初始化后无法更改——尝试修改该字段将导致编译错误。
在构造函数中,类成员在构造函数主体内被初始化。对于复杂对象,资源用于调用默认构造函数,然后进行赋值,最后销毁临时对象。
优点:
缺点:
所有成员在初始化列表中立即初始化,没有多余的操作和不可变字段的问题。
优点:
缺点: