构造函数的初始化列表 - 极悦
首页 课程 师资 教程 报名

构造函数的初始化列表

  • 2022-08-26 09:50:40
  • 706次 极悦

初始化列表是在构造函数中初始化对象数据成员的另一种技术。例如,构造函数

date::date(int m, int d, int y)
{
    month = m;
    day = d;
    year = y;
}

可以改为使用初始化列表来编写:

date::date(int m, int d, int y) : month(m), day(d), year(y)
{
}

内置类型和对象都可以使用初始化列表进行初始化。数组不能使用初始化列表进行初始化。

以这种方式初始化对象会导致构造函数调用。例如,如果一个被调用的类employee有一个date对象hire_date作为它的数据成员之一,我们可以使用一个初始化列表来初始化构造函数中的hire_date数据成员employee:

employee::employee(const string& name, int hire_month, int hire_day, int hire_year) :
                   employee_name(name), hire_date(hire_month, hire_day, hire_year)
{
}

初始化列表和范围问题

如果类的数据成员与构造函数的参数同名,则初始化列表“做正确的事”。例如,

date::date(int month, int day, int year) : month(month), day(day), year(year)
{
}

大致相当于

date::date(int month, int day, int year)
{
    this->month = month;
    this->day = day;
    this->year = year;
}

也就是说,编译器知道哪个month属于对象,哪个month是在成员函数中声明的局部变量。

构造函数执行的两个阶段.net

初始化阶段:全部类类型(class type)的成员都会在初始化阶段初始化,即便该成员没有出如今构造函数的初始化列表中。code

计算阶段:通常用于执行构造函数体内的赋值操做对象

使用常规构造函数赋值类对象:blog

#include <iostream>
using namespace std; 
class Test_A
{
public:
	Test_A()
	{
		cout<<"构造函数Test_A()"<<endl;
	}
	Test_A(const Test_A& t1)
	{
		cout<<"拷贝构造函数Test_A()"<<endl;
		m_age = t1.m_age;
	}
	Test_A& operator = (const Test_A& t1)
	{
		cout<<"重载赋值运算符operator="<<endl;
		m_age = t1.m_age;
		return *this;
	}
	~Test_A()
	{
		cout<<"析构函数~Test_A()"<<endl;
	}
public:
	int m_age;
};
class Test_B
{
public:
	Test_B(Test_A& t1)
	{
		m_b = t1;
	}
public:
	Test_A m_b;
};
/*此函数至关于一个舞台,展现此函数内对象的完整生命周期*/
void display() 
{
	Test_A t1;
	Test_B t2(t1);
}
int main()
{
	display();
	system("pause");
	return 0;
}

输出结果:生命周期

构造函数Test_A()
构造函数Test_A()
重载赋值运算符operator=
析构函数~Test_A()
析构函数~Test_A()

从输出结果中能够看出,在执行Test_B t2(t1)的过程:

先调用Test_A类的构造函数初始化成员对象 m_b (初始化阶段)

而后再调用Test_A类的重载赋值运算符函数,将t1赋值给m_b。 (计算阶段)

使用初始化列表(只需修改类Test_B中的构造函数):

class Test_B
{
public:
	Test_B(Test_A& t1):m_b(t1){};   //使用了构造函数的初始化列表
public:
	Test_A m_b;
};

输出结果:

构造函数Test_A()
拷贝构造函数Test_A()
析构函数~Test_A()
析构函数~Test_A()

从输出结果中能够看出,执行Test_B t2(t1)的过程:

在初始化成员对象 m_b时,直接调用Test_A类的拷贝构造函数进行初始化。

为何须要——初始化列表

1.性能的提升,对于内置类型,使用初始化列表和构造函数内赋值性能差异不是很大,可是对于类类型来讲,使用初始化列表,减小了一次计算阶段,若是是密集型类,效率将会更高。

2.成员的类型是没有默认构造函数的类。若没有提供显示初始化式,则编译器隐式使用成员类型的默认构造函数,若类没有默认构造函数,则编译器尝试使用默认构造函数将会失败,必须使用初始化列表

3.const成员或引用类型的成员。由于const对象或引用类型只能初始化,不能对他们赋值,必须使用初始化列表

选你想看

你适合学Java吗?4大专业测评方法

代码逻辑 吸收能力 技术学习能力 综合素质

先测评确定适合在学习

在线申请免费测试名额
价值1998元实验班免费学
姓名
手机
提交