【C++】初始化列表--再谈构造函数

在这里插入图片描述


个人主页 :阿然成长日记 点击可跳转
个人专栏: 数据结构与算法C语言进阶C++
不能则学,不知则问,耻于问人,决无长进

文章目录

  • 一、问题引入
  • 二、初始化的概念
  • 三、什么是初始化列表
  • 四、 初始化列表的格式
  • 五、初始化列表的使用
    • 1._a和_b已经有了缺省值,但是没有在初始化列表中显示写出。
    • 2.同时在初始化列表又有缺省值
  • 六、注意事项

一、问题引入

如下代码

class A {
//成员函数
private:
	int _a;	
	int _b;
	//const修饰的变量
	const int _t 
};

会出现如下结果

在这里插入图片描述
那这是为什么呢?

  • 我们知道,对于下面这个类A的成员变量_a和_b属于声明,还没有在内存中为其开辟出一块空间以供存放,真正开出空间则是在定义的时候,那何时定义呢?也就是使用这个类A去实例化出对象的时候。
  • 但是,对于_t变量来说,他是一个const成员变量,学过的都知道const修饰的变量必须为其赋初始值。编译后报出了错误说【必须初始化常量对象】,因为对于const修饰的变量在声明的时候是必须要去进行初始化的,也就是要给到一个值
  • 之前有讲过,若是我们自己不去实现构造函数的话,类中会默认提供一个构造函数来初始化成员变量,对于【内置类型】的变量不会处理,对【自定义类型】的变量会去调用它的构造函数。那么对于这里的_a1、_a2、_x都属于内置类型的数据,所以编译器不会理睬,可是呢const修饰的变量又必须要初始化,这个时候该怎么办呢

为了解决这个问题,祖师爷就提出了初始化列表

解决方法一: 给缺省值
使用C++11里面为内置类型不初始化打了一个补丁,在声明的位置给到一个初始化值,就可以很好地防止编译器不处理的问题。

const int _t = 1

方法二: 使用初始化列表
接下来就开始初始化列表的学习!

二、初始化的概念

  • 在了解【初始化列表】前,首先知道初始化的真正含义是什么

概念:在创建对象时,编译器通过调用构造函数,给对象中各个成员变量一个合适的初始值。

class Date
{
public:
	Date(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
private:
	int _year;
	int _month;
	int _day;
};

  • 虽然上述构造函数调用之后,对象中已经有了一个初始值,但是不能将其称为对对象中成员变量的初始化,构造函数体中的语句只能将其称为赋初值,而不能称作初始化。因为初始化只能初始化一次,而构造函数体内可以多次赋值

三、什么是初始化列表

以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个"成员变量"后面跟一个放在括号中的初始值或表达式

四、 初始化列表的格式

就拿之前写过的日期类为例

class Date
{
public:
	Date(int year, int month, int day)
		:_year(year)
		, _month(month)
		, _day(day)
	{}
private:
	int _year;
	int _month;
	int _day;
};
int main(void)
{
	Date d(2023, 3, 30);
	return 0;
}

五、初始化列表的使用

1._a和_b已经有了缺省值,但是没有在初始化列表中显示写出。

class A {
	//成员函数
public :
	A()
		:_t(888)
	{}
private:
	int _a = 666;
	int _b = 999;
	//const修饰的变量
	const int _t;
};
int main()
{
	A a;
	return 0;
}

【C++】初始化列表--再谈构造函数_第1张图片
由上图可以得出

  • 1.哪个对象调用构造函数,初始化列表是它所有成员变量定义的位置
  • 2.不管是否显式在初始化列表写,编译器都会为每个变量在初始化列表进行初始化

2.同时在初始化列表又有缺省值

class A {
	//成员函数
public :
	A()
		:_a(444)
		,_t(888)
	{}
private:
	int _a = 666;
	int _b = 999;
	//const修饰的变量
	const int _t;
};
int main()
{
	A a;
	return 0;
}

结果如下图
【C++】初始化列表--再谈构造函数_第2张图片
结论:

  • 这里要明确的一个概念是,缺省参数只是一个备份,若是我们没有去给到值初始化的话,编译器就会使用这个初始值,若是我们自己给到了明确的值的话,不会去使用这个缺省值了

六、注意事项

1. 每个成员变量在初始化列表中只能出现一次(初始化只能初始化一次)

2. 类中包含以下成员,必须放在初始化列表位置进行初始化
(1) 引用成员变量
通过编译可以看出,这个引用型成员变量_z需要被初始化,它必须要引用一个值
(2) const成员变量
这个在前面已经说到过了,const修饰的成员变量和构造函数对于内置类型不做处理产生了一个冲突,因此祖师爷就提出了【初始化列表】这个概念
(3) 自定义类型成员
写了有参构造编译器就不会提供默认构造。也就是说当存在自定义类型的时候,我们还是尽量使用初始化列表,

3.尽量使用初始化列表初始化,因为不管你是否使用初始化列表,对于自定义类型成员变量,一定会先使用初始化列表初始化。

4. 成员变量在类中声明次序就是其在初始化列表中的初始化顺序,与其在初始化列表中的先后次序无关

  • 所以建议我们在写初始化列表时,尽量顺序与成员变量定义一致。

你可能感兴趣的:(C++基础,c++,chrome,开发语言)