成员变量初始化

以下4中情况必须使用成员初始化列表:

  1. 当初始化一个reference member

  2. 当初始化一个const member

  3. 当调用一个base class的constructor,而它拥有一组参数时

  4. 当调用一个member class的constructor,而它拥有一组参数时

更有效率的使用成员初始化列表


以下代码两个示例

第一个:

class Person
{
public:
	Person()
	{
		m_strName = "zhangsan";
		m_nAge = 18;
	}
private:
	string m_strName;
	int m_nAge;
};

第二个:

class Person
{
public:
	Person(): m_strName("zhangsan")
	{
		m_nAge = 18;
	}
private:
	string m_strName;
	int m_nAge;
};

对于第一个示例编译器会先产生一个临时性的String object按照给定的初值,然后调用复制赋值运算符浆临时object指定给m_strName,然后在摧毁那个临时object,编译器可能扩张的结果:

Person()
{
	m_strName.string::string();

	string tmp("zhangsan");

	m_strName.string::operator=(tmp);

	tmp.string::~string();

	m_nAge = 18;
}

对于第二个示例编译器可能扩张的结果:

Person()
{
	m_strName.string::string("zhangsan");

	m_nAge = 18;
}

通过下面的示例验证上面的总结:

第一种初始化方式:

class Attribute
{
public:
	Attribute()
	{
		cout << "Attribute()"<<endl;
	}
	~Attribute()
	{
		cout << "~Attribute()" << endl;
	}
	Attribute(int nHp)
	{
		cout << "Attribute(int nHp)" << endl;
	}
	Attribute& operator=(const Attribute& objAttribute)
	{
		cout << "Attribute& operator=(const Attribute& objAttribute)"<< endl;
		return *this;
	}
};

class Person
{
public:
	Person()
	{
		m_strName = "zhangsan";
		m_objAttr = 100;
		m_nAge = 18;
	}
private:
	string m_strName;
	Attribute m_objAttr;
	int m_nAge;
};

{
	Person objPerson;
	cout << "end" << endl;
}

输出:

Attribute()
Attribute(int nHp)
Attribute& operator=(const Attribute& objAttribute)
~Attribute()
end
~Attribute()

第二种初始化方式:

class Person
{
public:
	Person():m_objAttr(100)
	{
		m_strName = "zhangsan";
		m_nAge = 18;
	}
private:
	string m_strName;
	Attribute m_objAttr;
	int m_nAge;
};

输出:

Attribute(int nHp)
end
~Attribute()

两种初始化方式很明显的看出差别,所以正确的初始化方式:

class Person
{
public:
	Person():m_strName("zhangsan"),m_objAttr(100)
	{
		m_nAge = 18;
	}
private:
	int m_nAge;
	string m_strName;
	Attribute m_objAttr;
};

注意


成员初始化列表的顺序由声明顺序决定,即使程序员没有按照声明顺序初始化最终还是按照声明顺序调整,并在函数体内的显示代码之前

例如:

Person():m_objAttr(100),m_strName("zhangsan")
{
	m_nAge = 18;
}

这种初始化方式虽然在列表中m_objAttr在m_strName之前初始化,但是程序最终还是按照声明顺序初始化,按照声明顺序初始化是指在初始化列表中的成员变量按照声明顺序初始化, 最终函数体内的成员变量初始化顺序不变,例如上面调整过的声明顺序是:

  1. m_nAge
  2. m_strName
  3. m_objAttr

最终初始化的顺序是成员初始化列表按照声明顺序初始化并且在显示初始化代码m_nAge = 18之前,即:

Person()
{
	m_strName.string::string("zhangsan");
	m_objAttr.Attribute::Attribute(100);
	m_nAge = 18;
}