类的构造函数可以用初始化列表来进行初始化。
一、使用初始化列表比在构造函数中进行赋值初始化效率高。
比较两者差别如下:
1、使用在构造函数中进行赋值初始化
#include "stdafx.h"
#include <iostream>
class TEST1
{
private:
int m_a;
public:
TEST1(){
std::cout << "Construct TEST1" << std::endl;
}
TEST1(const TEST1 & test1){
std::cout << "Copy constructor for TEST1" << std::endl;
this->m_a = test1.m_a;
}
TEST1 & operator = (const TEST1 & test1){
std::cout << "Assignment function for TEST1" << std::endl;
this->m_a = test1.m_a;
return *this;
}
~TEST1(){
std::cout << "Destruct TEST1" << std::endl;
}
};
class TEST2
{
private:
TEST1 test1;
public:
TEST2(const TEST1 & t1){
test1 = t1;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
TEST1 test1;
TEST2 test2(test1);
system("pause");
return 0;
}
此例中,TEST2类中使用了TEST1类的对象作为成员变量,执行结果为:
Construct TEST1
Construct TEST1
Assignment function for TEST1
2、若将上例中的TEST2用初始化列表来初始化,代码改变如下:
class TEST2
{
private:
TEST1 test1;
public:
TEST2(const TEST1 & t1):test1(t1){}
};
则运行结果为:
Construct TEST1
Assignment function for TEST1
以上差别说明,在构造函数中使用赋值方法进行初始化时,实际是分了两步,先调用TEST1的构造函数,然后再调用TEST1的赋值函数;而使用初始化列表的方式进行初始化时,则直接调用了TEST1的赋值函数。
二、初始化列表的初始化顺序
//本例测试初始化列表的初始化顺序
//结论为,不管初始化列表中写的顺序如何,在利用初始化列表进行初始化时是根据成员变量定义的顺序进行初始化的。
#include "stdafx.h"
#include <stdlib.h>
#include <iostream>
class INITLIST
{
public:
INITLIST() :m_i(0), m_j(){}
INITLIST(int i) :m_j(i), m_i(m_j){}
~INITLIST(){}
int Get_i()
{
return m_i;
}
int Get_j()
{
return m_j;
}
private:
int m_i, m_j;
};
int _tmain2(int argc, _TCHAR* argv[])
{
INITLIST obj(98);
std::cout << obj.Get_i() << std::endl;
std::cout << obj.Get_j() << std::endl;
system("pause");
return 0;
}
运行结果为:
-858993460
98
因为初始化列表的初始化顺序是根据成员变量定义的顺序进行初始化的。所以,当执行
INITLIST obj(98);
这条语句的时候,先对用m_i(m_j)对m_i进行初始化,而此时m_j的值未知,所以会出现上述负数结果,然后用m_j(i)对m_j进行初始化,得m_j的值为98。
若想使两个值均为98,则可以将成员变量的定义顺序修改为:
private:
int m_j, m_i;