C++入门学习——初始化列表

概念

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

class Date
{
public:
	//初始化列表
	Date(int year,int month,int day)
		:_year(year)
		,_month(month)
		,_day(day)
	{}

private:
	//声明
	int _year = 1;//缺省值
	int _month = 1;
	int _day;

	const int _n;
};

int main()
{
	//对象实例化
	Date d1(2024, 1, 31);

	return 0;
}

【注意】

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

class Date
{
public:
	Date(int year, int month, int day)
		:_year(year)
		, _month(month)
		, _day(day)
		, _n (2)
		,_year(3)
	{}

	
private:
	//声明
	int _year = 1;//缺省值
	int _month = 1;
	int _day;

	const int _n;
};

int main()
{
	//对象实例化
	Date d1(2024, 1, 31);

	return 0;
}

初始化列表能只能初始化一次,多次初始化会报错如下:
在这里插入图片描述

2. 类中包含以下成员,必须放在初始化列表位置进行初始化:

  • 引用成员变量
class A
{
public:
	A(int a )
		:_a(a)
	{
		cout << "A(int a=0)" << endl;
	}

private:
	int _a;
};

class Date
{
public:
	//初始化列表是每个成员变量定义初始化的位置
	Date(int year, int month, int day)
		,_month(2)
		,ref(year)
	{
		//赋值修改
		_year = year;
		_month = month;
		_day = day;
		//ref=year;//引用成员变量不能在函数体内初始化
	}

private:
	//声明
	int _year = 1;//缺省值
	int _month = 1;
	int _day;
	int& ref;
};

int main()
{
	//对象实例化
	Date d1(2024, 1, 31);
	return 0;
}
  • const成员变量
class Date
{
public:
	//初始化列表是每个成员变量定义初始化的位置
	Date(int year, int month, int day)
		:_n(1)//const成员变量必须使用初始化列表进行初始化
		,_month(2)
	{
		//赋值修改
		_year = year;
		_month = month;
		_day = day;
		//_n = 2;//const成员变量不能在函数体内初始化
	}

private:
	//声明
	int _year;
	int _month;
	int _day;

	const int _n;
};

int main()
{
	//对象实例化
	Date d1(2024, 1, 31);

	return 0;
}
  • 没有默认构造函数的自定义类型成员变量
class Date
{
public:
	//初始化列表是每个成员变量定义初始化的位置
	Date(int year, int month, int day)
		,_month(2)
		,_a(20)//没有默认构造函数的自定义类型成员变量必须在初始化列表进行初始化
	{
		//赋值修改
		_year = year;
		_month = month;
		_day = day;
	}

private:
	//声明
	int _year = 1;//缺省值
	int _month = 1;
	int _day;
	const int& ref;
	A _a;
	const int _n;
};

int main()
{
	//对象实例化
	Date d1(2024, 1, 31);

	return 0;
}

const成员变量、引用成员变量、没有默认构造函数的自定义类型成员变量必须在初始化列表内初始化的原因:

①初始化列表是对象的成员变量定义的地方。

②对象的内置类型成员变量在初始化列表定义时没有要求必须初始化,因此既可以在初始化列表进行初始化,也可以在构造函数体内初始化。

③而const成员变量、引用成员变量、没有默认构造函数的自定义类型成员变量不能先定义再初始化,它们在初始化列表内定义,并且必须在定义时就初始化,因此必须在初始化列表内初始化。

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

为什么会先使用初始化列表初始化?

因为自定义类型成员需要调用构造函数进行初始化,这个构造函数只能在初始化列表中调用,即使不写出来,编译器也会添加到初始化列表进行初始化

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

观察下面代码,会是哪个结果:

A. 输出1 1

B.程序崩溃

C.编译不通过

D.输出1 随机值

class A
{
public:
	A(int a)
		:_a1(a)
		,_a2(_a1)
	{}

	void Print() {
		cout << _a1 << " " << _a2 << endl;
	}

//private:
	int _a2;
	int _a1;
};

int main()
{
	A aa(1);
	aa.Print();
	return 0;
}

上面代码,类成员变量中先声明了_a2,再声明了_a1,因此初始化的顺序是先初始化_a2,再初始化_a1。先声明_a2就会先初始化_a2,用_a1初始化_a2,由于此时_a1还是随机值,因此_a2的值也是随机值,_a1使用a的值1进行初始化,因此,_a1的值为1。

image-20240713212721704

所以,建议类中的成员变量声明的顺序和初始化列表中初始化的顺序一致。

初始化列表其他注意点

class A
{
public:
	A(int a = 0, int b = 0)
		:_a(a)
	{
		cout << "A(int a=0)" << endl;
	}

private:
	int _a;
};

class Date
{
public:
	//初始化列表是每个成员变量定义初始化的位置
	Date(int year, int month, int day)
		:_n(1)//const成员变量必须使用初始化列表进行初始化
		, _month(2)
		, ref(2)
		, _a(20, 10)//没有默认构造函数的自定义类型成员变量必须在初始化列表进行初始化
		, _p((int*)malloc(sizeof(4)*10))//初始化列表不能写多条语句
	{
		//赋值修改
		_year = year;
		_month = month;
		_day = day;
		//_n = 2;//const成员变量不能在函数体内初始化
		if (_p == nullptr)
		{
			perror("malloc fail");
		}
	}

private:
	//声明
	//缺省值是给初始化列表用的
	int _year = 1;//缺省值
	int _month = 1;
	int _day;
	const int& ref;
	A _a;
	const int _n;
	int *_p;
};

int main()
{
	//对象实例化
	Date d1(2024, 1, 31);

	A a(5, 5);
	return 0;
}

①初始化列表是每个成员变量定义初始化的位置

②缺省值是给初始化列表用的

③初始化列表不能写多条语句

相关推荐

  1. C++ 初始化列表

    2024-07-16 21:10:01       70 阅读
  2. c++列表初始化

    2024-07-16 21:10:01       33 阅读
  3. C++:列表初始化

    2024-07-16 21:10:01       27 阅读
  4. C++ 初始化列表

    2024-07-16 21:10:01       17 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-16 21:10:01       66 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-16 21:10:01       70 阅读
  3. 在Django里面运行非项目文件

    2024-07-16 21:10:01       57 阅读
  4. Python语言-面向对象

    2024-07-16 21:10:01       68 阅读

热门阅读

  1. uni-app开发时自定义导航栏

    2024-07-16 21:10:01       23 阅读
  2. 新质生产力和新质战斗力如何深度耦合

    2024-07-16 21:10:01       19 阅读
  3. 【Python】Arcpy将excel点生成shp文件

    2024-07-16 21:10:01       21 阅读
  4. Linux批量更改文件后缀名

    2024-07-16 21:10:01       19 阅读
  5. android gradle 开发与应用(一) : Gradle基础

    2024-07-16 21:10:01       17 阅读
  6. Python学习4---迭代器和生成器的区别

    2024-07-16 21:10:01       24 阅读
  7. Linux基本命令(续)

    2024-07-16 21:10:01       21 阅读
  8. HTTPS

    HTTPS

    2024-07-16 21:10:01      19 阅读
  9. Vue3 基础

    2024-07-16 21:10:01       22 阅读
  10. redis-缓存三剑客

    2024-07-16 21:10:01       15 阅读
  11. python爬虫豆瓣电影TOP250

    2024-07-16 21:10:01       19 阅读