初始化类成员的两种方式:(1)使用初始化列表;(2)在构造函数体内进行赋值操作。
class Point
{
public:
Point(int xx, int yy) : x(xx), y(yy)
{
cout << "Constructor of Point" << endl;
}
private:
float x, y;
};
class Point
{
public:
Point(int xx, int yy)
{
x = xx;
y = yy;
cout << "Constructor of Point" << endl;
}
private:
float x, y;
};
但严格来说,上面两段代码只是能实现相同的功能(初始化Point类的对象),它们的本质并不相同,下面来说明原因。
构造函数的执行分为两个阶段:
(1)执行初始化列表:初始化类中的数据成员;
(2)执行构造函数体:一般是对类中的数据成员进行赋值操作。
初始化与赋值是不同的,所以上面两段代码只是功能上相同,但本质并不相同,前一个是初始化,后一个是赋值。
构造函数初始化列表*
. 提高效率,避免不必要的默认构造
通过构造函数初始化列表,成员变量在对象构造时直接用传递进来的值进行初始化,避免了先调用默认构造函数然后再赋值的过程。
-
构造函数体内赋值:
当你在构造函数体内赋值时,类的成员变量会先使用默认构造函数进行初始化,然后再在构造函数内部进行赋值。对于复杂的类,这样可能会引入不必要的性能开销。 -
初始化列表赋值:
初始化列表会直接调用对应的构造函数进行初始化,从而避免了对象的重复初始化,提升了性能。
示例:
class SkipList {
Compare compare;
public:
// 使用初始化列表进行初始化
SkipList(Compare cmp) : compare(cmp) {}
};
在这种写法中,compare
成员变量在对象创建时就直接用 cmp
来初始化,而不是先调用 Compare
类的默认构造函数,再在构造函数体内赋值