C++中的成员初始化列表

class Queue
{
private:
	//Node is a nestedstructure definition local to this c
	struct Node { Item item; struct Node * next; };
	enum { Q_SIZE = 10 };

	Node * front;  //pointer to front of Queue
	Node * rear;  //pointer to rear of Queue
	int items;  //current number of items in Queue
	const int qsize;  //maximum number of items in Queue
	...
public:
	...
};
Queue::Queue(int qs)
{
	front = rear = NULL;
	items = 0;
	qsize = qs;  //not acceptable
}

        对Queue类,上述构造函数的实现无法正常进行的原因在于qsize是常量,所以可以对它初始化,但不能给它赋值!从概念上说,调用构造函数时,对象将在括号中的代码执行前被创建。因此调用Queue(int qs)构造函数将导致程序首先给4个成员变量分配内存。然后程序流程进入到括号中,使用常规的赋值方式将值存储到内存中。因此,对于const数据成员,必须在执行到构造函数体前,即创建对象时进行初始化。C++提供了一种特殊的语法来完成上述工作——成员初始化列表(member initializer list)。因此Queue的构造函数可以写为

Queue::Queue(int qs) :qsize(qs)
{
	front = rear = NULL;
	items = 0;
}

        只有构造函数可以使用这种初始化列表语法。通常初值可以是常量,也可以是构造函数的参数列表中的参数。所以Queue的构造函数也可以写成

Queue::Queue(int qs) :qsize(qs), front(NULL), rear(NULL), items(0)
{
}

成员初始化列表的语法

        从概念上讲,上述关于qsize、front、rear、item的初始化工作是在对象创建时完成的,此时还未执行括号中的任何代码。要注意:

        这种格式只能用于构造函数;

        必须用这种形式来初始化非静态const数据成员(至少在C++11之前是这样的);

        必须用这种格式来初始化引用数据成员。这是因为引用与const数据类似,只能在被创建时进行初始化。如下

class Agent
{
private:
	Agency & belong;
	...
};
Agent::Agent(Agent & a) :belong(a) {...}

数据成员被初始化的顺序与他们出现在类声明中的顺序相同,与初始化器中的排列顺序无关。

C++11新增的类内初始化允许使用非静态const成员,因此Queue类的定义可写成

class Queue
{
private:
	//Node is a nestedstructure definition local to this c
	struct Node { Item item; struct Node * next; };
	enum { Q_SIZE = 10 };
	Node * front = NULL;  
	Node * rear = NULL;  
	int items = 0;  
	const int qsize = Q_SIZE;  
	...
public:
	...
};
这与使用成员初始化列表等价。然而,使用成员初始化列表的构造函数将覆盖相应的类内初始化。


猜你喜欢

转载自blog.csdn.net/wxn704414736/article/details/80256056