什么是"初始化列表"

总所周知,在C++的构造函数中,可以使用初始化列表来对新的对象进行初始化赋值,我们举个例子:

class ClassA
{
private:
	int _a;
	int _b;
};

这里有一个类,名为ClassA,里面包含_a_b两个int类型变量,如果我们不用初始化列表,它的构造函数应该这样写:

class ClassA
{
public:
	ClassA()
	{
		_a = 1;
		_b = 2;
	}

private:
	int _a;
	int _b;
};

但是我们如果使用初始化列表,可以写成这样

class ClassA
{
public:
	ClassA()
		:_a(1)
		, _b(2)
	{
	}

private:
	int _a;
	int _b;
};

在构造函数名下方使用:号衔接初始化列表,将各成员变量使用,号相连,就完成了初始化列表!

“隐藏坑”?初始化的顺序问题

我们先来看看以下代码:

class ClassA
{
public:
	ClassA()
		:_b(10)
		, _a(2 * _b)
	{
	}

private:
	int _a;
	int _b;
};

问题:构造出一个新的ClassA对象后,里面的_a和_b的初始值是什么?
答案:_a不确定,_b = 10

原因如下:
在初始化列表中,初始化顺序与列表顺序无关,而是与声明顺序有关!
在ClassA中,我们的声明顺序是

private:
	int _a;
	int _b;

因此,初始化列表会优先初始化_a,然后再初始化_b,如果有更多成员变量也是同理,会根据声明顺序依次初始化。
在题目中,虽然我们先写_b(10),但是按照声明顺序,代码会优先执行_a(2 * _b),此时_b还没有初始化,所以_a不会得到预期的20
随后,_b初始化,被赋值为10

因此,我们在使用初始化列表时,要尽可能让列表顺序与声明顺序一致,否则就容易造成初始化顺序不按预期的问题

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐