构造函数和初始化列表的关系和区别【详解】

构造函数和初始化列表关系和区别,以及为什么有初始化列表,和它的好处

一、构造函数和初始化列表的关系和区别

百度百科这样定义初始化列表:与其他函数不同,构造函数除了有名字,参数列表和函数体之外,还可以有初始化列表,初始化列表以冒号开头,后跟一系列以逗号分隔的初始化字段。
1、关系:从定义中我们可以知道初始化列表也是配合构造函数使用的,也就是说,构造函数可以使用初始化列表,也可以不使用(简单理解为初始化列表是构造函数的配件,可以有,也可以没有,但是有些场合必须使用初始化列表,第三部分会说)。
2、区别:我们以前都认为构造函数是给对象初始化,其实严格来说构造函数体中的语句只能将其称为赋初值,而初始化列表才是真正的初始化。因为初始化是在一个变量(或对象)定义的时候赋予初始值才叫初始化。如何理解构造函数是赋初始值,下面为什么有初始化列表中的三种情况你可以感受到。

二、为什么有初始化列表

因为类中有下面三种成员变量时,必须使用初始化列表来初始化
1、引用成员变量,因为引用必须在定义的时候初始化,而构造函数体中的语句是赋值,所以应该使用初始化列表初始化
2、const修饰的成员变量,因为const修饰的成员变量也必须在定义的时候初始化,所以必须使用初始化列表
3、没有默认构造的自定义类型成员变量,因为使用构造函数一定不可避免的会调用自定义类型成员变量的默认构造,然而使用初始化列表可以避免使用默认构造函数,直接调用该成员变量的拷贝构造(下面例子会讲到这些)

下面举例说明以上三种情况,如下:声明了一个Time类和Date类,Date类中声明了一个Time类类型变量

class Time //声明一个Time类,类中有三个成员变量,和一个有参构造函数
{
public:
	Time(int hour, int minuter, int second, int day)
	{
		_hour = hour;
		_minuter = minuter;
		_second = second;
	}

private:
	int _hour;
	int _minuter;
	int _second;
};

//声明一个Date类,类中有一个int类型成员变量、一个引用、一个const修饰、一个自定义类型
class Date
{
public:	
	Date(int year, int month, int day) //构造函数
	{
		_year = year;
		_month = _month;
		_day = day;
	}

private:
	int _year;
	int& _month; //引用
	const int _day; //const修饰
	Time _t; //没有默认构造的自定义类型
};

int main()
{
	Date d(2023, 11, 14);
	return 0;
}

vs2022中执行上面代码,会出现以下错误,并给出错误原因
在这里插入图片描述

解决方法就是使用初始化列表,如下所示:

class Time //声明一个Time类,类中有三个成员变量,和一个有参构造函数
{
public:
	Time(int hour, int minuter, int second, int day)
	{
		_hour = hour;
		_minuter = minuter;
		_second = second;
	}

private:
	int _hour;
	int _minuter;
	int _second;
};

//声明一个Date类,类中有一个int类型成员变量、一个引用、一个const修饰、一个自定义类型
class Date
{
public:	
	Date(int year, int month, int day, Time& t)
		:_year(year), _month(month), _day(day), _t(t) //初始化列表,_t(t)这个调用的是拷贝构造,为什么会调用拷贝构造,可以看本文【链接】
	{
	}

private:
	int _year;
	int& _month; //引用
	const int _day; //const修饰
	Time _t; //没有默认构造的自定义类型
};

int main()
{
	Time t(23, 43, 40); //实例化一个Time对象
	Date d(2023, 11, 14, t);
	return 0;
}

三、使用初始化列表的好处

当你了解了没有默认构造的自定义类型成员变量必须使用初始化列表的时候,初始化列表的好处也就出来了:可以减少一次默认构造的调用,当有大量对象的时候,使用初始化列表的好处还是很明显的,可以大大降低函数压栈带来的开销。所以我们能使用初始化列表尽量使用初始化列表。

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值