一.{}初始化
在c++98中,标准允许使用{}对数组或结构体元素进行统一的列表初始值设定:
struct mess
{
int _x;
string _str;
};
int main()
{
//注意,使用new的一定是指针
int* arr = new int[4] {1, 2, 3, 4};
//数组初始化
int arr[] = { 1,3,5,6 };
int arr[10] = { 0 };
//结构体初始化
mess m = { 1,"hello" };
return 0;
}
c++11扩大了使用列表初始化的范围,使其可以用于所有的自定义类型和内置类型是初始化,使用时,可以加=可以不加=:
struct mess
{
int _x;
string _str;
};
int main()
{
//数组初始化
int arr[] = { 1,3,5,6 };
int arr2[10]{ 0 };
//结构体初始化
mess m = { 1,"hello" };
mess m2{ 1,"hello" };
//整型初始化
int x1 = 10;
int x2{ 20 };
return 0;
}
如上,注意m2的第二种构造,使用的是{}列表!!!而不是(),因为如果使用(),那就是调用构造函数,但是咱们没有写带参的构造函数!!!
但是下面的这个类是写了构造函数的,所以当使用{}时,就是调用构造函数:
class Date
{
private:
int _year;
int _month;
int _day;
public:
Date(int year, int month, int day)
:_year(year)
, _month(month)
, _day(day)
{
cout << "构造函数" << endl;
}
};
int main()
{
Date d{ 2023,4,5 };
Date d2 = { 2024,5,6 };
Date d3(2024, 6, 7);
}
那d2和d3都是调用构造函数,难道没有什么区别吗?
有区别:d3就是直接调用构造函数,而d和d2本质上是类型转换!!!它是先使用列表构造一个date临时对象,再用临时对象去拷贝构造d3!!!,如下可以验证:
说明,必须是const引用才能接收初始化列表。
二.initializer_list
如上介绍,它是用于接收列表中的元素的,他是一个list,里面的元素都是const类型;该类型的对象是由编译器从初始化列表中构建出来的。
但注意,他和链表无关,支持迭代器
使用场景:
一般是作为构造函数的参数,c++11的stl就对不少容器添加了initializer_list作为函数参数的构造函数,基于这个原因,容器可以如下创建
本质和多参数构造的类型转换不同!!!!!,它是先生initializer_list对象,再用迭代器区间进行构造。
那我们自己手撕是vector能否这样构造呢?不可以,因为我们没有实现一个支持initializer_list的构造函数,所以应如下做:
或
写上这个构造函数,就能够使用列表初始化了