C++98标准中允许使用花括号对数组和自定义类型的变量进行初始化,C++11扩展了大括号的用途,允许使用花括号对所有的内置类型和自定义类型进行初始化,使用时,可以加=号,也可以不加。
对于自定义类型,当花括号中的常量与构造函数的形参匹配时,调用相应的构造函数。
//初始化列表
using namespace std;
class test
{
public:test(int a, double b):tow(a),three(b){cout << "test(int a,double b)" << endl;}int tow;double three;
};
int main()
{int a{ 11 };char b{ 'a' };double c{ 3.14 };int* d{ &a };test e{ 88,3.15 };test f{ "111",2,3.15 }; //本质是调用构造cout << d << endl;return 0;
}
与{}在形式上相同的并且容易混淆的是初始化列表,它是c++中的一种类型:
底层实际上是一个常量数组,存放在常量区,类成员的两个指针分别指向存放数据的常量区的开始和结束:
对于自定义类型,如果你想要让自己实现的类能够用{ }初始化,就需要新增一个构造,比如:
再比如map用初始化列表来初始化:
最外层的花括号被识别成了初始化列表,由于每个节点的数据域是pair,里层的花括号会去调用pair的构造函数来构造pair。
{}初始化和初始化列表是对内置类型和自定义类型初始化时底层的实现的差异,但是在语言层面实现的效果是相同的。对于内置类型或者自定义类型来说,用{}初始化是对C++98花括号功能的拓展,如果{}内的参数有相应的构造就去调用相应的构造,如果没有相应构造,并且{}内的参数类型与类成员变量类型匹配会依次赋值。
如果{}内的参数类型与成员变量不匹配,并且没有相应的构造,编译器就会寻找构造函数中是否有initializer_list类型的形参,然后执行构造的代码。